<?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: Pan Chasinga</title>
    <description>The latest articles on DEV Community by Pan Chasinga (@pancy).</description>
    <link>https://dev.to/pancy</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%2F18899%2F39d44a6a-b421-4afd-8f7b-c84305bceaa9.jpeg</url>
      <title>DEV Community: Pan Chasinga</title>
      <link>https://dev.to/pancy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pancy"/>
    <language>en</language>
    <item>
      <title>Taking Back Control in 2024</title>
      <dc:creator>Pan Chasinga</dc:creator>
      <pubDate>Wed, 08 Jan 2025 16:58:28 +0000</pubDate>
      <link>https://dev.to/pancy/taking-back-control-in-2024-10ah</link>
      <guid>https://dev.to/pancy/taking-back-control-in-2024-10ah</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/newyear"&gt;2025 New Year Writing challenge&lt;/a&gt;: Retro’ing and Debugging 2024.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In 2024, I hit a significant milestone, or rather, a ginormous roadblock. I turned 40, birthed my second child, and faced a year-long depression. Well, the only milestone I could think of was the 10-year anniversary of my programming journey.&lt;/p&gt;

&lt;p&gt;I started writing code as a hobby to experiment with creating graphics on computer. I was always a visual person -- I still am. Then as I became more adept to experiment, I used code to control hardware. Then I used code to &lt;a href="https://docs.google.com/presentation/d/1-jp3_NN8VSptDbLh7EdDBZiK7ZS-UK66u7W6ZUW7ktQ/present?slide=id.p" rel="noopener noreferrer"&gt;fight tyranny&lt;/a&gt;. My relationship with the computer used to be fun and adventurous.&lt;/p&gt;

&lt;p&gt;Then, life knocked on my door. It was time to make a living out of it. Either I had to abandon code or turn it into a real career. I started learning more conventional languages and frameworks and got better at writing web apps and servers. Years later, I successfully started my own &lt;a href="https://github.com/reactivex/rxgo" rel="noopener noreferrer"&gt;open-source project&lt;/a&gt;. Then I joined &lt;a href="https://www.recurse.com/" rel="noopener noreferrer"&gt;Recurse Center&lt;/a&gt; while doing nothing but coding and raising my first child for a month. It was peak fun.&lt;/p&gt;

&lt;p&gt;Then, I was flown to Silicon Valley for my first real engineering position with a YC-backed start-up. Silicon Valley! In my mind, I must have felt like a young Brad Pitt getting his first role in Hollywood. My excitement was overflowing. I thought my life was skyrocketing like TSLA stock in 2021.&lt;/p&gt;

&lt;p&gt;But I was wrong. That was the peak, and it was about to fall. I didn't like the life in the Bay Area. I was comfortable with much better earning and my wife could afford to stay home to raise my child, but something was missing. My relationship with code changed. It felt transactional, because I was in the confines of requirements and proprietary software. I could no longer contribute to open-source. My commit streak suddenly went out like the Christmas lights on the 26th of December.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;And that was also when I began to stop writing. What's the point? There was nothing to tell.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This strained relationship would continue regardless of how many jobs I changed. Sometimes, I could feel it returning for a while, working on a fun project, but it never lasted. I realized I was burning out. It was well-documented in this &lt;a href="https://dev.to/pancy/dealing-with-programmers-burnout-40b"&gt;2018 blog post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Eventually, I moved out of the Bay Area to where I could afford a home, and I welcomed the change. After all, living in a place where people's goals were to get a job in the FAANG and the moms were left with their children in the playground was boring. &lt;/p&gt;

&lt;p&gt;Then, the house became an enormous burden. I was tired of maintaining it. So, in 2024, I took up DIY. I learned and spent a ton of money and time on things from restoring cars to woodworking to soldering. I wanted to feel the maker in me once more. And if coding or writing cannot give me that, manning a power saw and cutting wood will. I took a lot of time in trial and error but much more time idling in fear. I gradually learned that it's my mind that's been betraying me the whole time. Wired for comfort, it was constantly fighting against my will. My will to write, code, and take apart cars. I constantly found myself feeling exhausted without having done much daily.&lt;/p&gt;

&lt;p&gt;Then, I started talking to someone I could trust. I read books on topics in healing. I stopped drinking entirely. I went back to working out, and when I couldn't, I committed to take 10k steps every day. I realized that to gain control of my mind, I have to feel good about my body. I wasn't going to let anyone -- Not even my family -- Stop me from taking care of myself.&lt;/p&gt;

&lt;p&gt;I'm happy to report to you that, after 4 months of actively and mindfully taking care of myself, I'm back writing again in 2025! I don't care about what to write about, I just write. I published my first &lt;a href="https://github.com/monetlang/uint256" rel="noopener noreferrer"&gt;Rust crate&lt;/a&gt; to &lt;a href="https://crates.io/crate/uint256" rel="noopener noreferrer"&gt;crates.io&lt;/a&gt; for everyone to see and use. I'm actively working on remodeling my boy's room. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Taking back control of my life has been my best accomplishment so far this year.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I hope everyone is making the best of 2025, but if you aren't, that is okay. Life is never a straight road, and it's full of detours and climbs. As long as you know yourself, you will be just fine.&lt;/p&gt;

&lt;p&gt;I will be seeing you quite often from now on. If you like to read more about mental health and taking care of yourself as a technologist, please follow me. If you're struggling with personal life and career, please follow me or drop a comment. I intend to write about these topics much more.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>newyearchallenge</category>
      <category>career</category>
      <category>mentalhealth</category>
    </item>
    <item>
      <title>How to set better 2025 Goals</title>
      <dc:creator>Pan Chasinga</dc:creator>
      <pubDate>Mon, 06 Jan 2025 20:26:58 +0000</pubDate>
      <link>https://dev.to/pancy/how-to-set-better-2025-goals-ocg</link>
      <guid>https://dev.to/pancy/how-to-set-better-2025-goals-ocg</guid>
      <description>&lt;p&gt;For me I've realized that, going back through my failed resolution goals, I have never set a higher value to change my behaviors. These are examples of those goals: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learn a new programming language X&lt;/li&gt;
&lt;li&gt;Learn how a computer works&lt;/li&gt;
&lt;li&gt;Become 10x more productive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are shallow, unmeasurable goals that are rather by-products of some higher-level behavioral changes that need to happen first. For instance, these are way better goals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make decisions I won't regret (my goal)&lt;/li&gt;
&lt;li&gt;Walk 10k steps each day&lt;/li&gt;
&lt;li&gt;Drink 10+ glasses of water&lt;/li&gt;
&lt;li&gt;Wake up at 4 am every morning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Granted these are just examples that are not for everyone. But to make a point - You won't be learning anything new or becoming 2x productive without changing yourself and/or your environment. It is foolish to think we can force our brain to take on something different without training it to adopt better, positive thinking. And that, my fellow devs, is because of your brain.&lt;/p&gt;

&lt;p&gt;Our brain is an ancient machine that's been programmed for comfort over hundreds of thousands of years of evolution, taking as little risk as possible to stay in its safest state. Before the Industrial Revolution, which was barely hundreds of years ago, our race was geared toward basic survival. We are basically carrying around an arcane, self-sabotaging CPU into the world where AI is increasingly becoming more powerful.&lt;/p&gt;

&lt;p&gt;So this New Year, instead of setting another unrealistic set of goals, set small but repeatable ones that compound to change your outlook and behaviors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are some of these goals you can set for yourself?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>newyearchallenge</category>
      <category>devresolutions2024</category>
      <category>productivity</category>
    </item>
    <item>
      <title>What is Semantic API?</title>
      <dc:creator>Pan Chasinga</dc:creator>
      <pubDate>Mon, 06 Jan 2025 19:38:26 +0000</pubDate>
      <link>https://dev.to/pancy/what-is-semantic-api-4i1j</link>
      <guid>https://dev.to/pancy/what-is-semantic-api-4i1j</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;💡 Semantic API is the strict practice of using literature and various design methods to curate, guide, guard, and improve the understanding of the user of a programming interface such as a library, command line tool, etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have been writing code for a good decade and what I have most struggled with (and convinced that the majority of developers are) was the opaqueness and obscurity of the libraries’ API and other interfaces, like command line tools. The user experience has been studied thoroughly on the user-facing software, but it is rarely a topic of serious discussion among developer communities when it comes to library, SDK, and tooling development.&lt;/p&gt;

&lt;p&gt;I’m convinced that the common UX methods cannot be simply applied to developers’ experience (that’s likely why XCode has a poor review). After all, the implicit goal for developers is to learn about the inner workings of what they are building. UX methods commonly strive to hide and abstract away the details in favor of friendliness to increase user retention. We have been applying the same principles to development with “developer-friendly” APIs that glaze over the greasy parts and hide them away by providing opinionated defaults for the users. We have built a magical culture of sloppy development clobbering together bits and pieces of dependencies into software that barely stands up on its own, all to gain short-term productivity.&lt;/p&gt;

&lt;p&gt;I believe the missing link to building sustainably is to Semantic APIs and toolings that encourage developers to learn more about the libraries they have downloaded from npm, pip, cargo, or any other package managers. Of course, this inevitably will require some sacrifice to the short-term gain in productivity, but the long-term gains will far outweigh the immediate friction. To design a semantic API, one has to put on a literature hat on top of an engineering one. Every names will have to effectively communicate the intention of itself.&lt;/p&gt;

&lt;p&gt;Let me give an example by demonstrating a subset of  &lt;code&gt;UInt256&lt;/code&gt; package I’m working on in Rust. It is a zero-dependency, from-the-ground-up implementation of a 256-bit integer type commonly used in Ethereum Virtual Machine. There are a few implementations out there, but they all do the same thing — Glazing over the potential knowledge of n-bit integers and ignoring the potential of users learning. Through their API and method designs it is clear the goal is to help experienced developers get things done without reinventing the wheel — In this case, implementing their very own 256-bit integer type. And thus, that was what I set out to do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="mi"&gt;0xff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x67&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x89&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x0a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0xbc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0xde&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0xf1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="mi"&gt;0x23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x67&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x89&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x0a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0xc2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x03&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0xd5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mi"&gt;0x12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x34&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x78&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0xab&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0xcd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0xef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mi"&gt;0x12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x34&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x78&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0xab&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0xcd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0xef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;UInt256Builder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.with_endian&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Endian&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Big&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.from_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note the following:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Without calling &lt;code&gt;with_endian(Endian)&lt;/code&gt; this operation will panic. There is no assumption of a default &lt;a href="https://dev.to/pancy/what-are-big-and-little-endians-91h"&gt;endianness&lt;/a&gt;. You are responsible to learn about and configure it. There is just no shortcut to not understand endianness or the user will quickly hit a roadblock converting between number types.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;from_ bytes([u8; 32])&lt;/code&gt; takes a bytes array of exactly 32 bytes, not vectors. Fixed-size bytes array ensure correctness of data, but more important, it ensures the user actually understand byte data. Vectors would have completely glazed over this for the sake of friendliness. But real friends expect the best from you and put you on the spot, not letting you off easy so you can have a beer early.&lt;/li&gt;
&lt;li&gt;If you want to pass a vector, you will be required to call &lt;code&gt;with_padding(Padding)&lt;/code&gt; to pad the "missing space" of the bytes vector provided. This check once again check the user’s understanding of what he’s doing. Check out the following example.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;UInt256Builder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.with_padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Padding&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;.with_endian&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Endian&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Big&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.from_partial_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0xcd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0xef&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="nf"&gt;.build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code is equivalent to passing the following raw bytes array to build a &lt;code&gt;UInt256&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0xcd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0xef&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;However, it is really hard to miss what one is doing when they are required to call &lt;code&gt;with_padding(Padding)&lt;/code&gt; . &lt;/p&gt;

&lt;p&gt;Hopefully this is enough to whet your appetite in designing a more semantic API and tooling for your users. They will surely hate you first, but the tough love is going to pay off and your users will appreciate you more as they gain long-term productivity and something immensely more powerful — knowledge — without having to rewrite something from scratch.&lt;/p&gt;

</description>
      <category>api</category>
      <category>devtool</category>
      <category>opensource</category>
    </item>
    <item>
      <title>What are Big and Little Endians?</title>
      <dc:creator>Pan Chasinga</dc:creator>
      <pubDate>Thu, 07 Nov 2024 12:00:41 +0000</pubDate>
      <link>https://dev.to/pancy/what-are-big-and-little-endians-91h</link>
      <guid>https://dev.to/pancy/what-are-big-and-little-endians-91h</guid>
      <description>&lt;p&gt;Are you familiar with Big and Little Endian, or have you heard about it somewhere along your programming journey but didn't pay much attention to it? In this short post, I will explain the concept in simple terms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Endianness&lt;/strong&gt; is the order in which bytes are stored and read in a computer's memory. It's a fundamental part of how computers understand and read bytes or any information input from the outside world.&lt;/p&gt;

&lt;p&gt;When a computer needs to read data like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;656669
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the computer reads the string of digits in Big Endian, it reads the most significant digits first. This means, 6, 5, 6, 6, 6, and 9, in that order. Therefore, the computer represents the data as the string of digits &lt;code&gt;65669&lt;/code&gt;, translated as "sixty-five thousand six hundred sixty-nine" or whatever you, the user of computers, wish it to represent. For instance, if the computer is told to read the string into ASCII, you would get it to spell &lt;code&gt;ABE&lt;/code&gt; for you.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;character&lt;/th&gt;
&lt;th&gt;decimal&lt;/th&gt;
&lt;th&gt;binary&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;65&lt;/td&gt;
&lt;td&gt;100 0001&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;66&lt;/td&gt;
&lt;td&gt;100 0010&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;69&lt;/td&gt;
&lt;td&gt;100 0101&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On the other hand, a small endian computer read the least significant digits first, meaning 9, 6, 6, 6, 5, and 6. This is a different string of digits, &lt;code&gt;966656&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In reality, computers only read in bits and bytes (8 bits). For example, if we are to read the integer &lt;code&gt;330&lt;/code&gt; into a computer program in Big endian, it would begin with the true bit representation of the integer:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;integer&lt;/th&gt;
&lt;th&gt;binary (in 2-byte word)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;330&lt;/td&gt;
&lt;td&gt;0000 0001 0100 1010&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;integer&lt;/th&gt;
&lt;th&gt;MSB&lt;/th&gt;
&lt;th&gt;LSB&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;330&lt;/td&gt;
&lt;td&gt;0x01&lt;/td&gt;
&lt;td&gt;0x4A&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A Big-endian computer (or program) will read the most significant bytes first, which is &lt;code&gt;0x01&lt;/code&gt; followed by &lt;code&gt;0x4a&lt;/code&gt;. So you end up getting the exact readable order of the bit string. &lt;/p&gt;

&lt;p&gt;A small-endian one, on the other hand, will read the least significant bytes first, which is &lt;code&gt;0x4A&lt;/code&gt; then &lt;code&gt;0x01&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In order to retrieve the right data, we have to know if a computer reads in which endianness. That's because you can get different data from when it was read. (&lt;code&gt;0x014A&lt;/code&gt; = 330 while &lt;code&gt;0x4A01&lt;/code&gt; = 18945).&lt;/p&gt;

&lt;p&gt;Here is a very simple test in Rust to prove it. We simply use the standard methods of a 16-bit (or 2-byte) unsigned integer type in Rust to read two-byte arrays which we intentionally swap the byte places.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;test_both_endians&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_be_bytes&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;0x01&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x4a&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_le_bytes&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;0x4a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x01&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;b&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;Endianness starts to become handy once you have to build a program that serializes and deserializes data. The concept is very simple. Let me know if you have any questions.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>data</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Getting Started with Goblins</title>
      <dc:creator>Pan Chasinga</dc:creator>
      <pubDate>Wed, 31 May 2023 14:57:25 +0000</pubDate>
      <link>https://dev.to/pancy/getting-started-with-goblins-31od</link>
      <guid>https://dev.to/pancy/getting-started-with-goblins-31od</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs0jow2sp24vhr3m8alfe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs0jow2sp24vhr3m8alfe.png" alt="Goblins Mascot" width="225" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Goblins?
&lt;/h2&gt;

&lt;p&gt;Goblins is a library for building distributed, peer-to-peer applications in &lt;a href="https://racket-lang.org/" rel="noopener noreferrer"&gt;Racket&lt;/a&gt; and &lt;a href="https://www.gnu.org/software/guile/" rel="noopener noreferrer"&gt;Guile&lt;/a&gt;. It is a part of the &lt;a href="https://spritely.institute/" rel="noopener noreferrer"&gt;Spritely&lt;/a&gt; ecosystem of ambitious projects attempting to fix the centralized internet.&lt;/p&gt;

&lt;p&gt;Goblins adopts the principle of &lt;a href="https://spritelyproject.org/news/what-is-captp.html" rel="noopener noreferrer"&gt;CapTP (Capability Transport Protocol)&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Object-capability_model" rel="noopener noreferrer"&gt;OCAP (Object Capability)&lt;/a&gt;. This guide aims to be a first practical introductory programming guide in Goblins for Racket programmers. Some experience programming in a Lisp dialect is useful, otherwise the general sections on OCAP and CapTP are still a good read.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Object Capability (OCAP)?
&lt;/h2&gt;

&lt;p&gt;OCAP has been around for decades, but it hasn't been easy to find introductory resources on the internet. The most accessible one being Mark Miller's paper &lt;a href="http://www.erights.org/elib/capability/duals/myths.html" rel="noopener noreferrer"&gt;Capability Myths Demolished&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;According to this &lt;a href="https://tutorial.ponylang.io/object-capabilities/object-capabilities.html#authority-hierarchies" rel="noopener noreferrer"&gt;Pony tutorial&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A capability is an unforgeable token that (a) designates an object and (b) gives the program the authority to perform a specific set of actions on that object.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The unforgeable token is, at the language level, just a reference to an object. In Object Capabilty's speak, "if you don't have it, you can't do anything with it".&lt;/p&gt;

&lt;p&gt;The core idea of it is that programs are built with &lt;em&gt;Principle of Least Authority (POLA)&lt;/em&gt;, instead of starting out with the complete opposite (maximum authority). But before we get ahead of ourselves, let's step back to talk about how programs behave today.&lt;/p&gt;

&lt;p&gt;When a user runs a program on the computer, that program is likely being run with that user's privilege level. That means aside from doing what it's supposed to do (like displaying a game window and interacting with I/O device for a game app), it can potentially do much more--whether it's reading and writing to local files, connecting to the network, and etc.--All under the radar of the unsuspecting user.&lt;/p&gt;

&lt;p&gt;This generic authority to do many things implicitly is known as ambient authority, and it comes with today's operating systems' &lt;a href="https://en.wikipedia.org/wiki/Access-control_list" rel="noopener noreferrer"&gt;access control list (ACL)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In object capability, every entity that attempts to create some side effect to interact with the world needs access to specific objects in order to do so. To give an example in a fictional programming language; To manipulate a window, a &lt;code&gt;scaleWindow(window: Window)&lt;/code&gt; procedure needs to be passed a &lt;code&gt;Window&lt;/code&gt; object. To access a file on a file system, a &lt;code&gt;readFile(file: File)&lt;/code&gt; procedure needs a &lt;code&gt;File&lt;/code&gt; object handed to it. This way, one can be certain that a program won't be capable of doing anything other than what it is requested to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Capability Transport Protocol (CapTP)?
&lt;/h2&gt;

&lt;p&gt;Similar to OCAP, it is quite difficult to find a gentle introduction to CapTP out there. CapTP takes the cue from OCAP and applies it to security of distributed, possibly networked systems. In CapTP, objects known as actors live in event loops known as vats. There can be one or more vats running on a machine's OS process, vats running on a machine's different processes or different machines entirely.&lt;/p&gt;

&lt;p&gt;Actors that live in the same vat are said to be &lt;em&gt;near&lt;/em&gt; one another, while those that live in different vats are said to be &lt;em&gt;far&lt;/em&gt; from one another. Nearby actors can communicate with one another by synchronously call each other (or &lt;em&gt;immediate call&lt;/em&gt;), while faraway actors have to communicate asynchronously with one another through message-sending (or &lt;em&gt;eventual send&lt;/em&gt;) and promise-resolving, as you will see in the next examples. In common scenarios, the network boundaries are abstracted away so that the programmers won't have to worry about them. For example, objects living in two different vats on the same machine and in two different vats on two different networked machines should appear analogous to the programmer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Setup
&lt;/h2&gt;

&lt;p&gt;Before anything else, make sure you have &lt;a href="https://racket-lang.org/" rel="noopener noreferrer"&gt;DrRacket&lt;/a&gt; installed and the IDE opened. You will need to install Goblins by going to File &amp;gt; Package Manager and type "goblins" in the Package Source box and hit enter to install the library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Immediately Calling an Object in a Vat
&lt;/h2&gt;

&lt;p&gt;In this first example, we will be creating a &lt;code&gt;car&lt;/code&gt; object that knows its location with a &lt;code&gt;'where&lt;/code&gt; method and is able to move to different ones with a &lt;code&gt;'move-to&lt;/code&gt; method. The object will be bootstrapped to live in a vat using an &lt;code&gt;a-run&lt;/code&gt; procedure. This way, it is simple to experiment on DrRacket's interactive prompt without having to run full vat programs.&lt;/p&gt;

&lt;p&gt;Paste the following code in the DrRacket editor, then hit run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;lang&lt;/span&gt; &lt;span class="nv"&gt;racket&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt; &lt;span class="nv"&gt;goblins&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt; &lt;span class="nv"&gt;goblins/actor-lib/bootstrap&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;;; Define a vat constructor.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="nv"&gt;a-vat&lt;/span&gt; 
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;make-vat&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;;; Define a vat runner.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;define-vat-run&lt;/span&gt; &lt;span class="nv"&gt;a-run&lt;/span&gt;
  &lt;span class="nv"&gt;a-vat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;;; Define a car object constructor.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;^car&lt;/span&gt; &lt;span class="nv"&gt;bcom&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;x&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;msg&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;next-x&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;next-y&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;cond&lt;/span&gt;
      &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nb"&gt;eq?&lt;/span&gt; &lt;span class="nv"&gt;msg&lt;/span&gt; &lt;span class="ss"&gt;'where&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cons&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
      &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nb"&gt;eq?&lt;/span&gt; &lt;span class="nv"&gt;msg&lt;/span&gt; &lt;span class="ss"&gt;'move-to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bcom&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;^car&lt;/span&gt; &lt;span class="nv"&gt;bcom&lt;/span&gt; &lt;span class="nv"&gt;next-x&lt;/span&gt; &lt;span class="nv"&gt;next-y&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 take a closer look at the &lt;code&gt;^car&lt;/code&gt; factory procedure (The &lt;code&gt;^&lt;/code&gt; is called the hard hat symbol; A naming convention for object factories). Without fuzzing too much over &lt;code&gt;bcom&lt;/code&gt; ("become"), let's just think of it as a wrapper that creates the next version of the object. As you'll see, when creating an object with &lt;code&gt;^car&lt;/code&gt;, the caller won't have to supply &lt;code&gt;bcom&lt;/code&gt; with a value.&lt;/p&gt;

&lt;p&gt;The outer &lt;code&gt;^car&lt;/code&gt; procedure is called to spawn or create an object (Note the optional&lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; arguments for the car's location which both default to 0). The procedure returns an anonymous procedure, which takes a symbol message and two optional arguments &lt;code&gt;next-x&lt;/code&gt; and &lt;code&gt;next-y&lt;/code&gt;. The message acts as a method or instruction within the &lt;code&gt;cond&lt;/code&gt; block. Currently, it accepts two messages &lt;code&gt;'where&lt;/code&gt; and &lt;code&gt;'move-to&lt;/code&gt;.  The &lt;code&gt;'where&lt;/code&gt; message returns a pair of current &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; coordinate of the car, and &lt;code&gt;'move-to&lt;/code&gt;, along with &lt;code&gt;next-x&lt;/code&gt; and &lt;code&gt;next-y&lt;/code&gt; arguments, transition the car's location to a new state.&lt;/p&gt;

&lt;p&gt;In the interactive prompt, try creating a &lt;code&gt;car&lt;/code&gt; object and calling it with messages like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; Create a new car object and assign to `my-car`.&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="nv"&gt;my-car&lt;/span&gt; 
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;a-run&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt; &lt;span class="nv"&gt;^car&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;;; Call the object with 'where symbol.&lt;/span&gt;
&lt;span class="c1"&gt;;; `$` stands for immediate call.&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;a-run&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt; &lt;span class="nv"&gt;my-car&lt;/span&gt; &lt;span class="ss"&gt;'where&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;;; Returns a pair '(0 . 0)&lt;/span&gt;

&lt;span class="c1"&gt;;; Call with 'move-to symbol and a new coordinate.&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;a-run&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt; &lt;span class="nv"&gt;my-car&lt;/span&gt; &lt;span class="ss"&gt;'move-to&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;;; Calling with 'where again to check the updated location.&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;a-run&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt; &lt;span class="nv"&gt;my-car&lt;/span&gt; &lt;span class="ss"&gt;'where&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;;; '(20 . 30)&lt;/span&gt;

&lt;span class="c1"&gt;;; Move to a different coordinate.&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;a-run&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt; &lt;span class="nv"&gt;my-car&lt;/span&gt; &lt;span class="ss"&gt;'move-to&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;;; Check the new location.&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;a-run&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt; &lt;span class="nv"&gt;my-car&lt;/span&gt; &lt;span class="ss"&gt;'where&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;;; '(3 . 5)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the &lt;code&gt;a-run&lt;/code&gt; procedure that was required to "simulate" a running vat in the prompt.&lt;/p&gt;

&lt;p&gt;Another way to define the &lt;code&gt;car&lt;/code&gt; factory is through a &lt;code&gt;method&lt;/code&gt; macro, which is a syntactic sugar to make it more familiar to OOP programmers. The objects created are analogous to the previous ones and can be called in a similar fashion.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; Import the methods macro.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt; &lt;span class="nv"&gt;goblins/actor-lib/methods&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;^car&lt;/span&gt; &lt;span class="nv"&gt;bcom&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;x&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;y&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;methods&lt;/span&gt;
    &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cons&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nf"&gt;move-to&lt;/span&gt; &lt;span class="nv"&gt;next-x&lt;/span&gt; &lt;span class="nv"&gt;next-y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bcom&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;^car&lt;/span&gt; &lt;span class="nv"&gt;bcom&lt;/span&gt; &lt;span class="nv"&gt;next-x&lt;/span&gt; &lt;span class="nv"&gt;next-y&lt;/span&gt;&lt;span class="p"&gt;))]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Eventual Send and Handling Promises in Many Vats
&lt;/h2&gt;

&lt;p&gt;In the case that two object lives in different vats or even on different machines, we invoke them using the eventual send &lt;code&gt;&amp;lt;-&lt;/code&gt; procedure instead of immediate call &lt;code&gt;$&lt;/code&gt; procedure.&lt;/p&gt;

&lt;p&gt;When we eventually send a message, the program returns a promise immediately without blocking. Then, we call the &lt;code&gt;on&lt;/code&gt; procedure with the returned promise and a callback. This shouldn't be a surprise if you have programmed in JavaScript before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;lang&lt;/span&gt; &lt;span class="nv"&gt;racket&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt; &lt;span class="nv"&gt;goblins&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt; &lt;span class="nv"&gt;goblins/actor-lib/bootstrap&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;;; Define a vat constructor.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="nv"&gt;a-vat&lt;/span&gt; 
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;make-vat&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;;; Define a vat runner.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;define-vat-run&lt;/span&gt; &lt;span class="nv"&gt;a-run&lt;/span&gt;
  &lt;span class="nv"&gt;a-vat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;;; Define another vat runner.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="nv"&gt;b-vat&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;make-vat&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;define-vat-run&lt;/span&gt; &lt;span class="nv"&gt;b-run&lt;/span&gt;
  &lt;span class="nv"&gt;b-vat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;;; Define a receiver constructor.&lt;/span&gt;
&lt;span class="c1"&gt;;; A receiver either receive a 'ping or 'pong message &lt;/span&gt;
&lt;span class="c1"&gt;;; from a sender and respond with a contrary message.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;^receiver&lt;/span&gt; &lt;span class="nv"&gt;bcom&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;cond&lt;/span&gt;
      &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nb"&gt;eq?&lt;/span&gt; &lt;span class="nv"&gt;msg&lt;/span&gt; &lt;span class="ss"&gt;'ping&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt; &lt;span class="s"&gt;"pong from ~a"&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
      &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nb"&gt;eq?&lt;/span&gt; &lt;span class="nv"&gt;msg&lt;/span&gt; &lt;span class="ss"&gt;'pong&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt; &lt;span class="s"&gt;"ping from ~a"&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt; &lt;span class="s"&gt;"~a doesn't understand you"&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)])))&lt;/span&gt;

&lt;span class="c1"&gt;;; Define a sender constructor.&lt;/span&gt;
&lt;span class="c1"&gt;;; A sender take a receiver and message as arguments, then &lt;/span&gt;
&lt;span class="c1"&gt;;; just immediately call the receiver object with that message.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;^sender&lt;/span&gt; &lt;span class="nv"&gt;bcom&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;recipient&lt;/span&gt; &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt; &lt;span class="nv"&gt;recipient&lt;/span&gt; &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's run the new code and return to the interpreter to experiment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; Define alice in a-vat.&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="nv"&gt;alice&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;a-run&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt; &lt;span class="nv"&gt;^receiver&lt;/span&gt; &lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="c1"&gt;;; Define bob in b-vat.&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="nv"&gt;bob&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;b-run&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt; &lt;span class="nv"&gt;^sender&lt;/span&gt; &lt;span class="s"&gt;"Bob"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="c1"&gt;;; Now Bob wants to send a 'ping message to Alice.&lt;/span&gt;
&lt;span class="c1"&gt;;; Bob being in the b-vat, we call `b-run` to bootstrap the vat.&lt;/span&gt;
&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;b-run&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt; &lt;span class="nv"&gt;bob&lt;/span&gt; &lt;span class="nv"&gt;alice&lt;/span&gt; &lt;span class="ss"&gt;'ping&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;;; not-callable: Not in the same vat: #&amp;lt;local-object ^receiver&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We got a &lt;code&gt;not-callable: Not in the same vat&lt;/code&gt; error because inside the definition of &lt;code&gt;^sender&lt;/code&gt; it immediately calls the &lt;code&gt;recipient&lt;/code&gt; with the &lt;code&gt;$&lt;/code&gt; but the &lt;code&gt;recipient&lt;/code&gt; is an object that lives in a different vat (&lt;code&gt;a-vat&lt;/code&gt;). Recall that objects living in different vats cannot immediately call one another. To prove the point, let's try to immediately call &lt;code&gt;alice&lt;/code&gt; from &lt;code&gt;b-vat&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;b-run&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt; &lt;span class="nv"&gt;alice&lt;/span&gt; &lt;span class="ss"&gt;'ping&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;;; not-callable: Not in the same vat: #&amp;lt;local-object ^receiver&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To fix this, we have to change to eventual send with &lt;code&gt;&amp;lt;-&lt;/code&gt;. This call is non-blocking and returns a promise to the caller. Let's try invoking &lt;code&gt;alice&lt;/code&gt; directly from &lt;code&gt;b-vat&lt;/code&gt; again, but this time with &lt;code&gt;&amp;lt;-&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; (b-run (&amp;lt;- alice 'ping))

;; #&amp;lt;local-promise&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get a promise in return! From our &lt;code&gt;b-vat&lt;/code&gt; land, we can handle a promise with the &lt;code&gt;on&lt;/code&gt; procedure, which takes a promise and a callback as arguments. Here is a callback that only prints out the respond from &lt;code&gt;alice&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="nv"&gt;my-promise&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;b-run&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="nv"&gt;alice&lt;/span&gt; &lt;span class="ss"&gt;'ping&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="nv"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;b-run&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt; &lt;span class="nv"&gt;my-promise&lt;/span&gt;
             &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;respond&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;displayln&lt;/span&gt; &lt;span class="nv"&gt;respond&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="c1"&gt;;; Prints "pong from Alice"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So to fix this just replace the &lt;code&gt;sender&lt;/code&gt; definition with the following so a &lt;code&gt;sender&lt;/code&gt; in one vat can "remotely" call (send) a &lt;code&gt;receiver&lt;/code&gt; in another vat:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;^sender&lt;/span&gt; &lt;span class="nv"&gt;bcom&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;recipient&lt;/span&gt; &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="nv"&gt;recipient&lt;/span&gt; &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;We have learned what OCAP and CapTP are and get our hands dirty coding with Goblins and learning immediate object calls in a single vat and sending messages between objects in different vats. Somehow, we have baredly scratched the surface.&lt;/p&gt;

&lt;p&gt;Currently Goblins is in rapid development and there will be changes along the way. Check out &lt;a href="https://gitlab.com/spritely/goblins" rel="noopener noreferrer"&gt;the repo&lt;/a&gt; for project updates.&lt;/p&gt;

</description>
      <category>lisp</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>racket</category>
    </item>
    <item>
      <title>Grokking Partial Application</title>
      <dc:creator>Pan Chasinga</dc:creator>
      <pubDate>Thu, 02 Jun 2022 23:03:10 +0000</pubDate>
      <link>https://dev.to/pancy/grokking-partial-application-e8l</link>
      <guid>https://dev.to/pancy/grokking-partial-application-e8l</guid>
      <description>&lt;p&gt;If you started programming in an imperative language such as Java like I did, learning to grok functional programming can be a daunting endeavor.&lt;/p&gt;

&lt;p&gt;What partial application, or known by some as "currying" after the late mathematician Haskell Curry, is applying a function to a value, which returns another function yet to be applied to another value.&lt;/p&gt;

&lt;p&gt;Look at the following function in JavaScript:&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;const&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you first apply this function to the first number 9, it replaces &lt;code&gt;a&lt;/code&gt; and returns the function &lt;code&gt;(b) =&amp;gt; 9 + b&lt;/code&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;const&lt;/span&gt; &lt;span class="nx"&gt;addNine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; (9) =&amp;gt; (b) =&amp;gt; 9 + n2&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; (b) =&amp;gt; 9 + n2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We end up with a half-applied function &lt;code&gt;addNine&lt;/code&gt; that, when applied to another number, will add it to number 9 which is being stored on the stack. In another word, the computation was being suspended until the next application.&lt;/p&gt;

&lt;p&gt;This is indeed different from the following function:&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;const&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we partially applied this function to a single value 5,&lt;code&gt;a&lt;/code&gt; would be substituted with a number while &lt;code&gt;b&lt;/code&gt; will be undefined, resulting in an execution of &lt;code&gt;5 + undefined&lt;/code&gt; which equals to &lt;code&gt;NaN&lt;/code&gt;, a very obscure result to ever be returned by a language. &lt;/p&gt;

&lt;p&gt;Functions in functional languages such as Ocaml and Haskell are curried, which means they apply to each value at a time no matter how many parameters they have. Take these two Haskell functions, which are similar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;add1&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;add1&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="n"&gt;add2&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;add2&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The line above each function's definition is the function's type declaration. They show that both functions are in fact the same—a two-step application process to the end value.&lt;/p&gt;

</description>
      <category>functional</category>
      <category>math</category>
      <category>hard</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Build a Decentralized App on IPFS using WebAssembly</title>
      <dc:creator>Pan Chasinga</dc:creator>
      <pubDate>Fri, 04 Feb 2022 15:58:47 +0000</pubDate>
      <link>https://dev.to/pancy/build-a-decentralized-app-on-ipfs-using-webassembly-46a4</link>
      <guid>https://dev.to/pancy/build-a-decentralized-app-on-ipfs-using-webassembly-46a4</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fax68bokg1f79pa3avo53.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fax68bokg1f79pa3avo53.jpg" alt="Pixelated Crabs" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;
Gimme Proof by Picklehart Liverthief





&lt;p&gt;In this fun and short tutorial, I'll show you how easy it is to build a fast front-end web app entirely in Rust, compile it to WebAssembly, and host it on the decentralized IPFS network. Yes, this is a Tutorial-to-learn-on-the-weekend-and-boast-to-your-DevOps-on-Monday you don't want to miss.&lt;/p&gt;

&lt;h2&gt;
  
  
  O, Wasm Fun!
&lt;/h2&gt;

&lt;p&gt;You may have heard in passing of &lt;a href="https://webassembly.org" rel="noopener noreferrer"&gt;WebAssembly&lt;/a&gt;. You may have thought it sounded pretty cool, but like other gazillion other techs of recent, it was cutting-edge and not ready for primetime.&lt;/p&gt;

&lt;p&gt;Well, now the time has passed, and although it might have not reached v1 yet, because many have been hacking on and building useful things with it, tooling has matured quickly. Now, it is very easy to start writing a web app entirely in Rust!&lt;/p&gt;

&lt;p&gt;For the unadulterated minds, Wasm is a new binary instruction format that lets your program run on the browser at native speed. You might not know it, but as you're reading this, your browser is hustling millions of lines of JavaScript code in real-time, occasionally hanging to clean up values that aren't being used. The fact that this website runs smoothly is due to hours of sweat and tear from developers on both the browser and the app you are using.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frsdpq8zse00zp1xseso6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frsdpq8zse00zp1xseso6.gif" alt="Big Head Silicon Valley Nodding" width="272" height="170"&gt;&lt;/a&gt;&lt;/p&gt;
One of the browser developers we interviewed





&lt;p&gt;Wasm is not specific to Rust. There are currently libraries in many languages that help compile native code to Wasm. However, Rust by far has the most matured tooling and ecosystem. Some benefits in writing Wasm apps in Rust are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rust is similar to TypeScript, but with a more robust type system and ownership tracking that enables developers to create fewer runtime errors typical to JavaScript and TypeScript.&lt;/li&gt;
&lt;li&gt;Rust has a good balance between low-level control and high-level developer ergonomics.&lt;/li&gt;
&lt;li&gt;Rust does not have a runtime, making &lt;code&gt;.wasm&lt;/code&gt; files small and downloading faster over the network.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Fun experiment&lt;/strong&gt;&lt;br&gt;
Try an under-developed, under-funded website, like paying for your utility bill on your municipal's web app or updating your benefits on your HR department's internal app. Record your observations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Ok, but why IPFS?
&lt;/h2&gt;

&lt;p&gt;Because we think Jeff Bezos has enough of our money to launch himself to space, and it is time to help host a better, less monopolistic internet. And what's a better way to start contributing to the cause than hosting our web app on each other's computers!&lt;/p&gt;

&lt;p&gt;IPFS, which stands for solar-system-dominating &lt;strong&gt;Interplanetary File System&lt;/strong&gt;, is a vast, global network of computers helping one another store and serve files. Sounds familiar? It's kind of like BitTorrent, except with much cooler and interoperable ways to link data and objects (which we will touch on later).&lt;/p&gt;

&lt;p&gt;IPFS and Wasm app are a perfect match because IPFS is decentralized, meaning it is more likely to cache and serve content on the "edge" nearer to the users while the Wasm app makes it even faster for the browser to load.&lt;/p&gt;

&lt;h2&gt;
  
  
  Convinced? Let's begin
&lt;/h2&gt;

&lt;p&gt;Here are a few things to get you set up for success:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install Rust&lt;/li&gt;
&lt;li&gt;Follow the Yew's Project Setup&lt;/li&gt;
&lt;li&gt;Open up your mind&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To sanity-check before we wander off climbing El Capitan without a rope, run the follow commands in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; cargo 1.56.0 &lt;span class="o"&gt;(&lt;/span&gt;4ed5d137b 2021-10-04&lt;span class="o"&gt;)&lt;/span&gt;

rustup target list | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'wasm32-unknown-unknown'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; wasm32-unknown-unknown &lt;span class="o"&gt;(&lt;/span&gt;installed&lt;span class="o"&gt;)&lt;/span&gt;

trunk &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; trunk 0.14.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your displayed versions will likely differ from here, but as long as none of the command makes the shell says "command not found" you should be good to join this quest.&lt;/p&gt;

&lt;p&gt;Now, when you're ready, create a new app by typing &lt;code&gt;cargo new --bin counter-app&lt;/code&gt; into your terminal, and check out the directory with &lt;code&gt;cd counter-app&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;From now on, when I say "root", it will mean inside this tada-app directory.&lt;/p&gt;

&lt;p&gt;At the root (I said it), run &lt;code&gt;cargo run&lt;/code&gt;. Without fail, the sample app Rust created for you should print out "hello, world".&lt;/p&gt;

&lt;p&gt;Open up the &lt;code&gt;Cargo.toml&lt;/code&gt; file, and add Yew crate as a dependency under the dependencies section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[package]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"counter-app"&lt;/span&gt;
&lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.1.0"&lt;/span&gt;
&lt;span class="py"&gt;edition&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2021"&lt;/span&gt;

&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="c"&gt;# Add this line&lt;/span&gt;
&lt;span class="py"&gt;yew&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.19"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run &lt;code&gt;cargo update&lt;/code&gt; to install the crate.&lt;/p&gt;

&lt;p&gt;Create an &lt;code&gt;index.html&lt;/code&gt; file with the following HTML content and save the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- UIkit CSS --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/uikit@3.10.1/dist/css/uikit.min.css"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- UIkit JS --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/uikit@3.10.1/dist/js/uikit.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/uikit@3.10.1/dist/js/uikit-icons.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Counter App&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This HTML file is the base document of our app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get familiar with Yew
&lt;/h2&gt;

&lt;p&gt;Yew is a library that glosses over all the nitty-gritty of building Rust into Wasm. If you have done some building in React, Vue, Angular, or Elm, and especially if you have with TypeScript, you will be up and running at full speed.&lt;br&gt;
Otherwise, back off on that gas a bit.&lt;/p&gt;

&lt;p&gt;Open up &lt;code&gt;src/main.rs&lt;/code&gt;, which is an entry point for all Rust app, and let's start with a counter app that consists of a button to increment a number value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/// Import all goodies from Yew.
use yew::prelude::*;

/// Our app's state. It is now just a unit struct with no property
/// because our state will be encapsulated within the Counter component.
struct App;

/// A Counter functional component ala React.
#[function_component(Counter)]
fn counter() -&amp;gt; Html {

    // Initializing the component's state.
    let counter = use_state(|| 0);

    // The onclick callback function.
    let onclick = {
        let counter = counter.clone();
        Callback::from(move |_| counter.set(*counter + 1))
    };

    // The component written in plain-old HTML, thanks to html! macro.
    html! {
        &amp;lt;div class="uk-position-center uk-text-center"&amp;gt;
            &amp;lt;button 
                {onclick}
                class="uk-button uk-button-primary uk-button-large"
            &amp;gt;
                { "+1" }
            &amp;lt;/button&amp;gt;
            &amp;lt;p&amp;gt;{ *counter }&amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
    }
}

/// The main App container.
impl Component for App {

    // The internal types that are required to be implemented to comply Component trait.
    type Message = ();
    type Properties = ();

    // The constructor function, which instantiates the App.
    fn create(_ctx: &amp;amp;Context&amp;lt;Self&amp;gt;) -&amp;gt; Self {
        App
    }

    // The view lifecycle function, which renders the App.
    fn view(&amp;amp;self, _ctx: &amp;amp;Context&amp;lt;Self&amp;gt;) -&amp;gt; Html {
        html! {
            &amp;lt;Counter /&amp;gt;
        }
    }
}

/// Start the Yew app
fn main() {
    yew::start_app::&amp;lt;App&amp;gt;();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope you can guess a lot from just reading the code. If you are new to Rust, some things might have stuck out, like the &lt;code&gt;#[...]&lt;/code&gt; just above the &lt;code&gt;Counter&lt;/code&gt; component function and &lt;code&gt;html! { ... }&lt;/code&gt; surrounding the HTML code. They are macros, the magic dragons that keeps Rust code simple and boiler-plate free.&lt;/p&gt;

&lt;p&gt;Note that we could even include a class attribute to the button element to style our button with our CSS styling library. Neat!&lt;/p&gt;

&lt;p&gt;Now, for the moment of truth, run &lt;code&gt;trunk serve&lt;/code&gt; and watch in awe as the super speedy web app unwinds on port 8080 (or whatever port it listens on).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8vmy53vlo7lm196tbgh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8vmy53vlo7lm196tbgh.gif" alt="Counter app" width="640" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Fun with buttons
&lt;/h2&gt;

&lt;p&gt;Now that we had our morale boosted, it is a good time to learn about props and states. Let's add two more buttons - one for decrementing the number and another for resetting it to 0. &lt;/p&gt;

&lt;p&gt;First of all, let's change our App component into a functional component, instead of a struct. Replace the App struct and its lifecycle methods (everything within &lt;code&gt;impl App&lt;/code&gt; block) with the following functional component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[function_component(App)]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;app&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;use_state&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;html!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Counter&lt;/span&gt; &lt;span class="o"&gt;/&amp;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;One thing that React did well was to promote functional over class-based components. Functional components are stateless and easier to understand, and Yew carries on with that convention.&lt;/p&gt;

&lt;p&gt;We are using &lt;code&gt;use_state&lt;/code&gt; hook, which behaves similarly to the one in React. Instead of providing 0 as the initial state, we pass an anonymous function (or as Rust calls a &lt;em&gt;closure&lt;/em&gt;) with a value of 0. Because Rust infers 0 as a 32-bit integer (i32) type by default, we have to coerce it to a 64-bit unsigned integer type by using the keyword &lt;code&gt;as&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We need to communicate with the DOM inside the &lt;code&gt;Counter&lt;/code&gt; component since all the buttons are wrapped in there. This is where we pass props in. Our props will only contain the state because we just want the child components to change it from inside &lt;code&gt;Counter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On top of &lt;code&gt;counter&lt;/code&gt; function, define a &lt;code&gt;TodoProps&lt;/code&gt; struct with a &lt;code&gt;state&lt;/code&gt; field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Properties,&lt;/span&gt; &lt;span class="nd"&gt;PartialEq)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;TodoProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UseStateHandle&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="o"&gt;&amp;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;Note the macro clause &lt;code&gt;#[derive(...)]&lt;/code&gt; before the struct definition. It implements &lt;code&gt;Properties&lt;/code&gt; and &lt;code&gt;PartialEq&lt;/code&gt; traits, generating necessary implementation at compile time. All props are required to implement these two traits.&lt;/p&gt;

&lt;p&gt;Now, add the props as a parameter to &lt;code&gt;counter&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[function_component(Counter)]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;TodoProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&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 now, miraculously, &lt;code&gt;Counter&lt;/code&gt; now accepts a props name &lt;code&gt;state&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[function_component(App)]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;app&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;use_state&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nd"&gt;html!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Counter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;/&amp;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;Let's head back to &lt;code&gt;counter&lt;/code&gt; function. We want to increment the state when a button is pressed. Let's define an &lt;code&gt;increment&lt;/code&gt; callback to do that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[function_component(Counter)]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;TodoProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="py"&gt;.state&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nn"&gt;Callback&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;state&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="p"&gt;}&lt;/span&gt;
    &lt;span class="nd"&gt;html!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"uk-position-center uk-text-center"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; 
          &lt;span class="n"&gt;onclick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"uk-button uk-button-primary uk-button-large"&lt;/span&gt;
        &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"+1"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="py"&gt;.state&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;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;With these changes, if you run &lt;code&gt;trunk serve&lt;/code&gt; now, you should see a button incrementing the number like before. In fact, saving the changes should reload the app in the browser automatically!&lt;/p&gt;

&lt;p&gt;All we have to do now is to repeat, add &lt;code&gt;decrement&lt;/code&gt; and &lt;code&gt;reset&lt;/code&gt; callbacks, and two more buttons that take them as callbacks. Here is the complete code with three buttons:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;yew&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&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="nd"&gt;#[derive(Properties,&lt;/span&gt; &lt;span class="nd"&gt;PartialEq)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;TodoProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UseStateHandle&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[function_component(Counter)]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;TodoProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="py"&gt;.state&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nn"&gt;Callback&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;state&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="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;decrement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="py"&gt;.state&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nn"&gt;Callback&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;state&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="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;reset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="py"&gt;.state&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nn"&gt;Callback&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="nf"&gt;.set&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="p"&gt;};&lt;/span&gt;

    &lt;span class="nd"&gt;html!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"uk-position-center uk-text-center"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;
                &lt;span class="n"&gt;onclick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"uk-button uk-button-primary uk-button-large"&lt;/span&gt;
            &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"+1"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;
                &lt;span class="n"&gt;onclick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"uk-button uk-button-primary uk-button-large"&lt;/span&gt;
            &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;
                &lt;span class="n"&gt;onclick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;decrement&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"uk-button uk-button-primary uk-button-large"&lt;/span&gt;
            &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"-1"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="py"&gt;.state&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[function_component(App)]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;app&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;use_state&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;html!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Counter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;yew&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;start_app&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="o"&gt;&amp;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;The latest counter app should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmgzc4i9n06tj7hs49ukr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmgzc4i9n06tj7hs49ukr.gif" alt="Counter app with 3 buttons" width="640" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we wrap up app building, peek into the &lt;code&gt;dist&lt;/code&gt;. You will likely find a &lt;code&gt;.js&lt;/code&gt;, &lt;code&gt;.wasm&lt;/code&gt;, and a &lt;code&gt;.html&lt;/code&gt; files. Trunk had built and compiled the app into a bundle of files in this directory, ready to be served with any HTTP server.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Fun experiment&lt;/strong&gt;&lt;br&gt;
 If you have Python installed, try running HTTP server within &lt;code&gt;dist&lt;/code&gt; with the command &lt;code&gt;python3 -m http.server 8080&lt;/code&gt; or &lt;code&gt;python -m SimpleHTTPServer 8080&lt;/code&gt; for Python2. Alternatively, Node &lt;code&gt;http-server&lt;/code&gt; works too.&lt;br&gt;
What are your observations? Epiphanies? Record them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Deploy to IPFS
&lt;/h2&gt;

&lt;p&gt;IPFS network consists of many nodes running &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fipfs%2Fgo-ipfs" rel="noopener noreferrer"&gt;IPFS&lt;/a&gt;, coordinating with each other to help store and distribute digital content over the internet. At a high level, the only different you need to know is that IPFS is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Content-addressed&lt;/strong&gt;&lt;br&gt;
Unlike the world wide web today, which mostly serve content at a location address like &lt;a href="https://coolapp.com/public/cat1.jpg" rel="noopener noreferrer"&gt;https://coolapp.com/public/cat1.jpg&lt;/a&gt;, IPFS identify a piece (or pieces) of content based on its hash, or Content Identifier (CID). It does not matter where the file (or bits of it) is located on the internet. IPFS will retrieve that file based on the hash you provide. For example, on IPFS-compatible browsers like Brave or Puma, check out NFTSchool website on IPFS with &lt;code&gt;ipfs://bafybeicsyilnu4rxrjlerad5kzstvgio3n62qlxektwqudj4x53vaexxiu&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Immutable&lt;/strong&gt;&lt;br&gt;
Because you retrieve content on IPFS by its digital fingerprint, contents on the network are unchangeable. There is no way to save a puppy JPEG at &lt;a href="https://coolapp.com/public/cat1.jpg" rel="noopener noreferrer"&gt;https://coolapp.com/public/cat1.jpg&lt;/a&gt; to troll with cat lovers or even remove the image and leave them with a 404 Cat Not Found.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The trickiest part of hosting content on IPFS is its "garbage-collecting" nature. To avoid congesting the storage, unused contents are pruned from the hard disk(s) of the storage node(s). To keep a piece of content online and available, we must pin it to the persistent storage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run IPFS locally
&lt;/h2&gt;

&lt;p&gt;We will deploy and serve our Wasm counter app on a local IPFS node running on our machine. &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fdocs.ipfs.io%2Fhow-to%2Fwebsites-on-ipfs%2Fsingle-page-website%2F%23install-ipfs-desktop" rel="noopener noreferrer"&gt;Download the IPFS Desktop node&lt;/a&gt;, which gives you a nice UI on top of the IPFS server.&lt;/p&gt;

&lt;p&gt;Open IPFS Desktop app, navigate to the File tab, and drag the &lt;code&gt;dist&lt;/code&gt; folder from our project into the app window. Once it's loaded, you should see the directory appears in the app:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F32bd4pwptir7yisgtor7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F32bd4pwptir7yisgtor7.png" alt="IPFS Desktop app screen" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the ellipsis icon to the right of the item (the three-dotted icon), click &lt;strong&gt;Share Link&lt;/strong&gt;, then click &lt;strong&gt;Copy&lt;/strong&gt;. Paste the URL in a browser, then you should be able to see your counter app!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Fun experiment&lt;/strong&gt;&lt;br&gt;
Try pinning the app by clicking Set Pin from the same menu. Read up quickly on pinning, then come back here a changed person.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  IPFS Gateway
&lt;/h2&gt;

&lt;p&gt;You might have noticed that the link you got starts with HTTPS protocol, like &lt;a href="https://ipfs.io/ipfs/QmNtFreJ5pn6dH1xeNYYdqmYnWuWgLn5akijeFxrE5giad" rel="noopener noreferrer"&gt;https://ipfs.io/ipfs/QmNtFreJ5pn6dH1xeNYYdqmYnWuWgLn5akijeFxrE5giad&lt;/a&gt;. Because IPFS is not supported in some browsers, there are several HTTP gateway that acts as a safe passage into the IPFS-hosted content via HTTP. This link connects to a gateway provided by ipfs.io.&lt;/p&gt;

&lt;p&gt;In browsers like Brave or Puma, users will be able to browse using IPFS natively with &lt;code&gt;ipfs://QmNtFreJ5pn6dH1xeNYYdqmYnWuWgLn5akijeFxrE5giad&lt;/code&gt;. We can think of these browsers as the direct gateways to IPFS without a "web2" middleman sitting in the middle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pinning services
&lt;/h2&gt;

&lt;p&gt;Running the IPFS node locally and serving the app on your own is a fun exercise, but if you shut down your computer, your node and your app will likely go down. The fastest way to get up and running is to upload your app to a pinning service such as &lt;a href="https://estuary.tech/" rel="noopener noreferrer"&gt;Estuary&lt;/a&gt;, &lt;a href="https://web3.storage/" rel="noopener noreferrer"&gt;Web3.storage&lt;/a&gt;, or deploy directly to &lt;a href="https://fleek.co" rel="noopener noreferrer"&gt;Fleek&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Immutability's crux
&lt;/h2&gt;

&lt;p&gt;If you have been thinking it through, you would have realized what a headache it would be to update our app. If you just removed a single line or a print statement from your app and re-deployed, you will end up with a completely different CID. That's why the current internet is based on mutable addresses - So users can always find their way back regardless of the content.&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fdocs.ipfs.io%2Fconcepts%2Fipns%2F%23example-ipns-setup-with-cli" rel="noopener noreferrer"&gt;Interplanetary Name System (IPNS)&lt;/a&gt; and &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fdocs.ipfs.io%2Fconcepts%2Fdnslink%2F%23publish-content-path" rel="noopener noreferrer"&gt;DNSLink&lt;/a&gt; on how to link a static CID and domain name to your IPFS app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fck2DMH8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fck2DMH8.gif" width="478" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webassembly</category>
      <category>rust</category>
      <category>ipfs</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Building an NFT Store on Flow: Part 2</title>
      <dc:creator>Pan Chasinga</dc:creator>
      <pubDate>Mon, 31 Jan 2022 19:42:54 +0000</pubDate>
      <link>https://dev.to/pancy/building-an-nft-store-on-flow-part-2-2i0o</link>
      <guid>https://dev.to/pancy/building-an-nft-store-on-flow-part-2-2i0o</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This is a sequel of the two-part tutorial. If you have not, check out &lt;a href="https://dev.to/pancy/building-a-flow-nft-pet-store-part-1-4bn9"&gt;part 1&lt;/a&gt; and work your way back here!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this second part of the tutorial, we will work on building the UI with React.js and Flow's &lt;a href="https://docs.onflow.org/fcl/" rel="noopener noreferrer"&gt;fcl.js&lt;/a&gt; library to interact with the on-chain smart contract we deployed in the &lt;a href="https://dev.to/pancy/building-a-flow-nft-pet-store-part-1-4bn9"&gt;first part&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Because learning React is unfortunately out of the scope, if you need a quick introduction or brush-up on React, head over to &lt;a href="https://reactjs.org/tutorial/tutorial.html" rel="noopener noreferrer"&gt;Intro to React&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Very often, especially for &lt;a href="https://ethereum.org/en/dapps/" rel="noopener noreferrer"&gt;decentralized applications&lt;/a&gt; whose back-ends rely heavily on blockchains and other decentralized technology, the user experience is what makes or breaks them. Quite often, the user-facing part &lt;em&gt;is&lt;/em&gt; the only crucial part in a dapp.&lt;/p&gt;

&lt;p&gt;In this section, we will be working on the UI for the pet store app in React.js. While you're expected to have some familiarity with the library, I will do my best to use common features instead of advanced ones.&lt;/p&gt;

&lt;p&gt;After we are done, we will have built a simple marketplace app on the local blockchain that users can mint and query their NFTs, which looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnftschool.dev%2Fassets%2Fimg%2Fflow-nft-marketplace-finish.21bbfc21.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnftschool.dev%2Fassets%2Fimg%2Fflow-nft-marketplace-finish.21bbfc21.png" alt="finished-marketplace" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up
&lt;/h3&gt;

&lt;p&gt;Make sure you are in the project directory (next to &lt;code&gt;package.json&lt;/code&gt;). Install the following packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; —save @onflow/fcl @onflow/types nft.storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Flow packages will help in connecting our React app to the Cadence code. The &lt;code&gt;nft.storage&lt;/code&gt; package will help in uploading the image during minting and retrieving data from Filecoin/IPFS network. In order to do so, you will need to &lt;a href="https://nft.storage/" rel="noopener noreferrer"&gt;sign up&lt;/a&gt; and generate an API key. After you have signed up, navigate to the "API Keys" tab, and click to create a new key, as shown here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnftschool.dev%2Fassets%2Fimg%2Fnft-storage-api-keys.723dd8f4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnftschool.dev%2Fassets%2Fimg%2Fnft-storage-api-keys.723dd8f4.png" alt="Screenshot of NFT.Storage API Keys page" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy and save the key as we will need it later on when we work on the minting logic.&lt;/p&gt;

&lt;p&gt;To get styling out of the way, let's download &lt;a href="https://github.com/dhg/Skeleton/releases/download/2.0.4/Skeleton-2.0.4.zip" rel="noopener noreferrer"&gt;Skeleton CSS&lt;/a&gt;, unzip all the CSS files into the &lt;code&gt;src&lt;/code&gt; directory, and import all the &lt;code&gt;.css&lt;/code&gt; files in the &lt;code&gt;App.css&lt;/code&gt; main stylesheet in the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* App.css */&lt;/span&gt;

&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"./skeleton.css"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"./normalize.css"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;/* import all other CSS files if there are any */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, run the app with &lt;code&gt;npm run start&lt;/code&gt;, the React app should open in the browser on &lt;code&gt;http://localhost:3000&lt;/code&gt;. Keep the browser open to see the updates as you save your code progress.&lt;/p&gt;

&lt;p&gt;Let's make the app our own by removing the template from React. In your editor, open &lt;code&gt;App.js&lt;/code&gt; and remove all the current HTML, leaving only the &lt;code&gt;&amp;lt;div className="App"&amp;gt;&lt;/code&gt; DOM tags.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* DOM code removed */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;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;After you saved the file, the app in the browser should reload and appear empty.&lt;/p&gt;

&lt;p&gt;Now, create a new directory named &lt;code&gt;components&lt;/code&gt; inside &lt;code&gt;src&lt;/code&gt; to keep our reusable components with &lt;code&gt;mkdir -p src/components&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Inside the newly created &lt;code&gt;components&lt;/code&gt; directory, create a new file named &lt;code&gt;Form.js&lt;/code&gt; and add the following code below. This component will be with which users can submit and mint new NFTs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// components/Form.js&lt;/span&gt;

&lt;span class="c1"&gt;// Import the `FileSelector` module, which does not exist yet. &lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;FileSelector&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./FileSelector&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Collect the information of a pet and manage as a state&lt;/span&gt;
&lt;span class="c1"&gt;// and mint the NFT based on the information.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPet&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;

  &lt;span class="c1"&gt;// Helper callback functions to be passed to input elements' onChange.&lt;/span&gt;

  &lt;span class="c1"&gt;// Update the state of the pet's name.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;setPet&lt;/span&gt;&lt;span class="p"&gt;({...&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Update the state of the pet's breed.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setBreed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;breed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;setPet&lt;/span&gt;&lt;span class="p"&gt;({...&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Update the state of the pet's age.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setAge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;setPet&lt;/span&gt;&lt;span class="p"&gt;({...&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FileSelector&lt;/span&gt; &lt;span class="na"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;setPet&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setPet&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="na"&gt;for&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"nameInput"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Pet's name&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
              &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"u-full-width"&lt;/span&gt;
              &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
              &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Max"&lt;/span&gt;
              &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"nameInput"&lt;/span&gt;
              &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="na"&gt;for&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"breedInput"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Breed&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;select&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"u-full-width"&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"breedInput"&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setBreed&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;option&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Labrador"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Labrador&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;option&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;option&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Bulldog"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Bulldog&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;option&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;option&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Poodle"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Poodle&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;option&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;select&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="na"&gt;for&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"ageInput"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Age&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;select&lt;/span&gt;
                &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"u-full-width"&lt;/span&gt;
                &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"ageInput"&lt;/span&gt;
                &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setAge&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;
                  &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;option&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;option&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;
                &lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;select&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button-primary"&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Mint"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5rem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;maxWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;350&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will get an error since the &lt;code&gt;FileSelector.js&lt;/code&gt; component we imported in the code does not yet exist. So, create the &lt;code&gt;FileSelector.js&lt;/code&gt; file next to &lt;code&gt;Form.js&lt;/code&gt; to handle the image uploading.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// components/FileSelector.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// We are passing `pet` and `setPet` as props to `FileSelector` so we can&lt;/span&gt;
&lt;span class="c1"&gt;// set the file we selected to the pet state on the `Form` outer scope&lt;/span&gt;
&lt;span class="c1"&gt;// and keep this component stateless.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;FileSelector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPet&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// Read the FileList from the file input component, then&lt;/span&gt;
  &lt;span class="c1"&gt;// set the first File object to the pet state.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;readFiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setPet&lt;/span&gt;&lt;span class="p"&gt;({...&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;files&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="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="na"&gt;for&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"fileInput"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Image&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Add readFiles as the onChange handler. */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;readFiles&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;FileSelector&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you import &lt;code&gt;Form.js&lt;/code&gt; component into &lt;code&gt;App.js&lt;/code&gt; and insert it anywhere inside the main &lt;code&gt;App&lt;/code&gt; container, you should see your form that looks similar what you see here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnftschool.dev%2Fassets%2Fimg%2Fform.5b981711.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnftschool.dev%2Fassets%2Fimg%2Fform.5b981711.png" alt="Screenshot of form component" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Minting
&lt;/h2&gt;

&lt;p&gt;Here comes the most crucial step of all NFTs--Minting. Minting an NFT is officially creating it and establishing its existence and initial ownership on-chain, making the token "authentic". For this step, we will hook up the &lt;code&gt;Mint&lt;/code&gt; button to actually mint a token based on user's input.&lt;/p&gt;

&lt;p&gt;First, let's head over to &lt;code&gt;/src/flow/transaction&lt;/code&gt; and create a new JavaScript file named &lt;code&gt;MintToken.tx.js&lt;/code&gt;. This module acts as an interface between the Cadence code in &lt;code&gt;MintToken.cdc&lt;/code&gt;  instead of the Flow CLI we used previously in &lt;a href="https://dev.to/pancy/building-a-flow-nft-pet-store-part-1-4bn9"&gt;part 1&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here I create a JavaScript module that interacts with each Cadence transaction or script and name it to reflect the Cadence code, appended by &lt;code&gt;.tx.js&lt;/code&gt; or a transaction or &lt;code&gt;.sc.js&lt;/code&gt; for a script. This is not a requirement and you're free to name them however you want.&lt;/p&gt;

&lt;p&gt;Since there are quite a few things involved in the minting process, we are going to go through a bit slowly on this one. We will create a &lt;code&gt;mintToken&lt;/code&gt; function that takes a &lt;code&gt;pet&lt;/code&gt; object and does the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Upload to NFT.storage.&lt;/strong&gt; This uploads the metadata and image asset to NFT.storage, and retrieves the returned metadata that includes the &lt;a href="https://proto.school/anatomy-of-a-cid/01" rel="noopener noreferrer"&gt;CID&lt;/a&gt; of the data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send a minting transaction&lt;/strong&gt; with the metadata to Flow (in this case, the name, age, breed, and the CID of the data stored on IPFS).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Return the Flow transaction ID&lt;/strong&gt; if successful.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;First, let's sketch up some placeholder functions to outline the steps:&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="c1"&gt;// MintToken.tx.js&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mintToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;uploadToStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;txId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;mintPet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;txId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// We will fill in these functions next&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;uploadToStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mintPet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&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;h3&gt;
  
  
  1. Upload to NFT.Storage
&lt;/h3&gt;

&lt;p&gt;Next, fill in the body of &lt;code&gt;uploadToStorage&lt;/code&gt; function. You will need to replace the placeholder string with your API key from &lt;a href="https://nft.storage/" rel="noopener noreferrer"&gt;NFT.Storage&lt;/a&gt;. Note that in production, you will be reading this key as an environment variable for better security.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;NFTStorage.store(...)&lt;/code&gt; takes an object with arbitrary attributes and two required attributes, &lt;code&gt;image&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt;. (Contrary to its name, the &lt;code&gt;image&lt;/code&gt; attribute does not require an image file. It takes a &lt;code&gt;File&lt;/code&gt; object which can contain any type of asset.)&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;description&lt;/code&gt; attribute can be any arbitrary text up to $MAXLENGTH.&lt;/p&gt;

&lt;p&gt;Then, we return the metadata returned from the call to the caller.&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="c1"&gt;// Import required modules from nft.storage&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NFTStorage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;File&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nft.storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DROP_YOUR_API_KEY_HERE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Initialize the NFTStorage client&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NFTStorage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;API_KEY&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;uploadToStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Call `store(...)` on the NFTStorage client with an object&lt;/span&gt;
  &lt;span class="c1"&gt;// containing all of pet's attributes, and required image and&lt;/span&gt;
  &lt;span class="c1"&gt;// description attributes.&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;store&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.jpg`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image/jpg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;'s metadata`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// If all goes well, return the metadata.&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;metadata&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;h3&gt;
  
  
  2. Send a minting transaction
&lt;/h3&gt;

&lt;p&gt;Once we have the metadata uploaded to NFT.storage, we will have to send a transaction to mint the token with the metadata. Let's fill in the &lt;code&gt;mintPet&lt;/code&gt; function.&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="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;fcl&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@onflow/fcl&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@onflow/types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;cdc&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./MintToken.cdc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mintPet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// Convert the metadata into a {String: String} type. See below.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;toCadenceDict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Build a list of arguments&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;args&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Dictionary&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="c1"&gt;// Fetch the Cadence raw code.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cdc&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Send the transaction!&lt;/span&gt;
  &lt;span class="c1"&gt;// Note the `userAuthz` function we have not implemented.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;payer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authz&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;proposer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authz&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authorizations&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authz&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;999&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="c1"&gt;// Call `fcl.decode` to get the transaction ID.&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;txId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;encoded&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// This waits for the transaction to be sealed, which is a recommended way.&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;txId&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;onceSealed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Return the transaction ID&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;txId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Helper function to convert `pet` object to a {String: String} type.&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;toCadenceDict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Copy the pet object so we don't mutate the original.&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;newPet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// Delete the `image` attribute that contains a `File` object.&lt;/span&gt;
  &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;newPet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Return an array of [{key: string, value: string}].&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newPet&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;k&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;As you can see, our &lt;code&gt;mintPet&lt;/code&gt; function is a little involved.&lt;/p&gt;

&lt;p&gt;The first step we took was to convert the &lt;code&gt;pet&lt;/code&gt; data to a type our Cadence contract understands, which a dictionary of type &lt;code&gt;{String: String}&lt;/code&gt;. Basically, if the object looks like this:&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="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Max&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;age&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;span class="nx"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bulldog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then have to convert it to an array of &lt;code&gt;{key: string, value: string}&lt;/code&gt; in JavaScript:&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="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Max&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="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;age&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3&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="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;breed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bulldog&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;This was what &lt;code&gt;toCadenceDict&lt;/code&gt; function did, plus deleting the &lt;code&gt;image&lt;/code&gt; attribute from the pet object because we didn't need it for minting on Flow.&lt;/p&gt;

&lt;p&gt;After properly converting the object, we had to build a payload by calling &lt;code&gt;fcl.args&lt;/code&gt; and pass an array of arguments. In this case, the metadata of type &lt;code&gt;[{key: string, value: string}]&lt;/code&gt;.  To facilitate this, we used types from &lt;code&gt;fcl.types&lt;/code&gt; library.&lt;/p&gt;

&lt;p&gt;Next, we fetch the corresponding &lt;code&gt;MintToken.cdc&lt;/code&gt; code as a raw string. This is a standard way of fetching raw text from another module.&lt;/p&gt;

&lt;p&gt;Now comes the meaty part of this function: Sending a transaction.&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;const&lt;/span&gt; &lt;span class="nx"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;payer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authz&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;proposer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authz&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authorizations&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authz&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
  &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;999&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;payload&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;There are a few FCL functions to send a transaction, but &lt;code&gt;fcl.send([...])&lt;/code&gt; is the most straightforward one.&lt;/p&gt;

&lt;p&gt;We pass the Cadence &lt;code&gt;code&lt;/code&gt; to &lt;code&gt;fcl.transaction&lt;/code&gt;, and any integer from 0 - 999 to &lt;code&gt;fcl.limit&lt;/code&gt; for the gas fee limit we are happy with. The &lt;code&gt;payload&lt;/code&gt; is the metadata we converted previously.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;payer&lt;/code&gt;, &lt;code&gt;proposer&lt;/code&gt;, and &lt;code&gt;authorizations&lt;/code&gt; accept a function known as &lt;em&gt;authorization function&lt;/em&gt;, which decides the account (and effectively the keys) used to authorize the transaction. (If you're interested in deep-diving into this, check out &lt;a href="https://docs.onflow.org/fcl/reference/api/#authorization-function" rel="noopener noreferrer"&gt;Authorization Function&lt;/a&gt;). Here, &lt;code&gt;fcl&lt;/code&gt; provided an &lt;code&gt;authz&lt;/code&gt; default authorization function to makes signing with the emulator account easier.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Return the transaction ID
&lt;/h3&gt;

&lt;p&gt;Now all that is left to do is to return to the main &lt;code&gt;mintToken&lt;/code&gt; function with a transaction ID:&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="c1"&gt;// This is a fallible function.&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mintToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// The metadata contains the attribute `url` which is an IFPS URL&lt;/span&gt;
  &lt;span class="c1"&gt;// pointing to the data.json.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;uploadToStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// We want to include the IPFS URL to the blockchain, so we can&lt;/span&gt;
  &lt;span class="c1"&gt;// "unpack" the token data when we query it later. So we create&lt;/span&gt;
  &lt;span class="c1"&gt;// a new object with all of the pet's attributes plus `url`.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;txId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;mintPet&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;txId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Don't forget to export the function.&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;mintToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our &lt;code&gt;mintToken&lt;/code&gt; function is now ready. Let's return to &lt;code&gt;Form.js&lt;/code&gt;, add a &lt;code&gt;handleSubmit&lt;/code&gt; handler (right after &lt;code&gt;setAge&lt;/code&gt; function), and pass to the &lt;code&gt;onSubmit&lt;/code&gt; prop on the &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element.&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="c1"&gt;// Form.js&lt;/span&gt;

&lt;span class="c1"&gt;// On the top most of the module&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;mintToken&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../flow/transaction/MintToken.tx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// ... setAge function ...&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;mintToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&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="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* ... other elements ... */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This wraps up token minting. Now you can test the UI, select an image file, fill up the metadata on the form, and click the mint button to mint NFTs on the local net.&lt;/p&gt;

&lt;p&gt;Now is the time to fill up your coffee and take a well-deserved break before we move on to the last bit of the tutorial--Querying tokens' data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Querying the token
&lt;/h2&gt;

&lt;p&gt;Now that we can mint our pet tokens, let's build another form UI to query them for metadata and image.&lt;/p&gt;

&lt;p&gt;We are going to reuse the minting form. Once we're done, it will look similar to this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/.%2Fimages%2Fflow-nft-marketplace%2Fquery-form.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/.%2Fimages%2Fflow-nft-marketplace%2Fquery-form.png" alt="Query form to query tokens" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I know Mary is obviously &lt;em&gt;not&lt;/em&gt; a Bulldog, but you will get a chance to add your breed options later.&lt;/p&gt;

&lt;p&gt;Let's start by creating &lt;code&gt;QueryToken.jsx&lt;/code&gt; file inside the &lt;code&gt;/components&lt;/code&gt; directory.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// QueryForm.jsx&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1rem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;paddingTop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5rem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;maxWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;350&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auto&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;QueryForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;selectedId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSelectedId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMetadata&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;allTokenIds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAllTokenIds&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;getTokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Set mock IDs for now&lt;/span&gt;
      &lt;span class="nf"&gt;setTokenIds&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="mi"&gt;2&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;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nf"&gt;getTokens&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="c1"&gt;// Empty handler for now...&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;row&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="nx"&gt;htmlFor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;idInput&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Pet&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;s ID&amp;lt;/label&amp;gt;
            &amp;lt;select
              className="u-full-width"
              type="number"
              id="idInput"
              onChange={(event) =&amp;gt; setId(parseInt(event.target.value))}
            &amp;gt;
              {
                // We want to display token IDs that are available.
                allTokenIds.map(i =&amp;gt; &amp;lt;option value={i}&amp;gt;{i}&amp;lt;/option&amp;gt;)
              }
            &amp;lt;/select&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;input className="button-primary" type="submit" value="Query" /&amp;gt;
      &amp;lt;/form&amp;gt;
      {
        // We only display the table if there&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
        &lt;span class="nx"&gt;metadata&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MetadataTable&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt; : nul&lt;/span&gt;&lt;span class="err"&gt;l
&lt;/span&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MetadataTable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;table&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;u-full-width&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;thead&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;tr&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="c1"&gt;// Skip the `url` attribute in metadata for the table headings.&lt;/span&gt;
            &lt;span class="nx"&gt;field&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;th&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/th&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/tr&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/thead&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;tbody&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;tr&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="c1"&gt;// Skip displaying the url.&lt;/span&gt;
              &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
              &lt;span class="c1"&gt;// Display the image as &amp;lt;img&amp;gt; tag.&lt;/span&gt;
              &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;td&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;60px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
                  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/td&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="p"&gt;);&lt;/span&gt;
              &lt;span class="c1"&gt;// Default is to display data as text.&lt;/span&gt;
              &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;td&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/td&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/tr&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/tbody&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/table&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;QueryForm&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As usual, we need to create JavaScript "bindings" to two Cadence scripts &lt;code&gt;GetTokenMetadata.cdc&lt;/code&gt; and &lt;code&gt;GetAllTokenIds.cdc&lt;/code&gt;. We will start with &lt;code&gt;GetAllTokenIds.sc.js&lt;/code&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="c1"&gt;// GetAllTokenIds.sc.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;fcl&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@onflow/fcl&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./GetAllTokenIds.cdc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getAllTokenIds&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// Fetch the `GetAllTokenIds.cdc` script as text.&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;cdc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Read the script, send it, and wait for the response.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;script&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cdc&lt;/span&gt;&lt;span class="p"&gt;)]);&lt;/span&gt;

  &lt;span class="c1"&gt;// Decode the response into a JavaScript array of IDs.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tokenIds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;encoded&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Sort the IDs in ascending order and return the array.&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;tokenIds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;getAllTokenIds&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hopefully, by now you are already an expert. It's worth switching back and taking a look at &lt;code&gt;GetAllTokenIds.cdc&lt;/code&gt; to see how the Javascript bindings and Cadence scripts interact.&lt;/p&gt;

&lt;p&gt;Next up, we create &lt;code&gt;GetTokenMetadata.sc.js&lt;/code&gt; to execute the &lt;code&gt;GetTokenMetadata.cdc&lt;/code&gt; script.&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="c1"&gt;// GetTokenMetadata.sc.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;fcl&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@onflow/fcl&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@onflow/types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./GetTokenMetadata.cdc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getTokenMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;script&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;args&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;)]),&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;encoded&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;getTokenMetadata&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, you can review &lt;code&gt;GetTokenMetadata.cdc&lt;/code&gt; to see the relationships between the interfaces offered and how we used them in this function.&lt;/p&gt;

&lt;p&gt;Now we are ready to return to &lt;code&gt;QueryForm.jsx&lt;/code&gt;.  Import the functions we worked on:&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="c1"&gt;// QueryForm.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Import these functions&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;getAllTokenIds&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../flow/script/GetAllTokenIds.sc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;getTokenMetadata&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../flow/script/GetTokenMetadata.sc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;toGatewayURL&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nft.storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;QueryForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;allTokenIds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAllTokenIds&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;selectedId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSelectedId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMetadata&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;getTokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Instead of dummy token IDs, we call `getAllTokenIds`&lt;/span&gt;
      &lt;span class="c1"&gt;// to get real IDs of all existing tokens.&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getAllTokenIds&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nf"&gt;setTokenIds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nf"&gt;getTokens&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Add this block to the submit handler.&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Call the `getTokenMetadata` function and extract the&lt;/span&gt;
      &lt;span class="c1"&gt;// IPFS URL from the data returned.&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getTokenMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;dataURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;toGatewayURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// Fetch the URL to get a JSON response, which contains&lt;/span&gt;
      &lt;span class="c1"&gt;// an `image` attribute.&lt;/span&gt;
      &lt;span class="c1"&gt;// create a new metadata object and set the metadata to the value.&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dataURL&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;newdata&lt;/span&gt; &lt;span class="o"&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;metadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;toGatewayURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
      &lt;span class="nf"&gt;setMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newdata&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Token ID does not exist!&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="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ...The component code unchanged...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;useEffect&lt;/code&gt; callback, we replaced the stubbed ID array with the call to&lt;br&gt;
&lt;code&gt;getAllTokenIds&lt;/code&gt; function, which executed &lt;code&gt;GetAllTokenIds.cdc&lt;/code&gt; and returned an&lt;br&gt;
array of existing token IDs. We then call &lt;code&gt;setTokenIds&lt;/code&gt; to set &lt;code&gt;allTokenIds&lt;/code&gt; to&lt;br&gt;
the array. This is used to fill up the &lt;code&gt;&amp;lt;option&amp;gt;&lt;/code&gt; element with the IDs and act as&lt;br&gt;
the UI guard to make sure users can only choose the available tokens to query.&lt;/p&gt;

&lt;p&gt;In the "empty" &lt;code&gt;handleSubmit&lt;/code&gt; handler function, which is called each time the query button&lt;br&gt;
is clicked, we added a &lt;code&gt;try-catch&lt;/code&gt; block which called &lt;code&gt;getTokenMetadata&lt;/code&gt; with the ID user&lt;br&gt;
selected in &lt;code&gt;selectedId&lt;/code&gt;, and return the metadata of the selected NFT.&lt;/p&gt;

&lt;p&gt;Remember that as part of metadata in minting, we included the &lt;code&gt;url&lt;/code&gt; attribute from the&lt;br&gt;
NFT.storage upload. This &lt;code&gt;url&lt;/code&gt; is an IPFS URL in the form of &lt;code&gt;ipfs://&amp;lt;CID&amp;gt;/data.json&lt;/code&gt;.&lt;br&gt;
We are interested in this URL because it points to the JSON data containing the URL to&lt;br&gt;
the pet image we uploaded to IPFS. To fetch it using JavaScript, we had to convert the IPFS&lt;br&gt;
URL to the HTTP gateway URL with &lt;a href="https://nftstorage.github.io/nft.storage/client/modules.html#toGatewayURL" rel="noopener noreferrer"&gt;&lt;code&gt;toGatewayURL&lt;/code&gt;&lt;/a&gt;. Once we fetched the JSON and convert to an object, we access the&lt;br&gt;
&lt;code&gt;image&lt;/code&gt; attribute, convert it to HTTP URL, and include it along with other data in the new metadata&lt;br&gt;
object we set the state with &lt;code&gt;setMetadata&lt;/code&gt;. It is then ready for the &lt;code&gt;MetadataTable&lt;/code&gt; component&lt;br&gt;
to display.&lt;/p&gt;

&lt;p&gt;Note that in the case of error, &lt;code&gt;handleSubmit&lt;/code&gt; would call &lt;code&gt;window.alert&lt;/code&gt; and display a simple popup&lt;br&gt;
window to notify the user.&lt;/p&gt;

&lt;p&gt;There was no change needed for the component code.&lt;/p&gt;

&lt;p&gt;Now, try to mint an NFT with the mint form, and query it with the query form! Hopefully, it should all work as intended.&lt;/p&gt;

&lt;p&gt;Congratulations! You have single-handedly built a NFT minting and querying marketplace on Flow. This has been a great achievement!&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;Flow's focus on developer's experience and the accessibility of its smart contract language Cadence, plus its low gas fee and high throughput, make it an extremely promising blockchain to build NFT-related apps on.&lt;/p&gt;

&lt;p&gt;Because NFTs have assets that need to be stored off-chain permanently, using NFT.Storage to store them on the Filecoin network is a natural way to go as the first step to launch your NFT app on Flow quickly.&lt;/p&gt;

&lt;p&gt;If you are still hungry to learn more about Flow and NFT.Storage, here is a non-exhaustive list of the resources to tackle next:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dive into the &lt;a href="https://docs.onflow.org/cadence/language/" rel="noopener noreferrer"&gt;Cadence Language Reference&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Explore &lt;a href="https://docs.onflow.org/fcl/" rel="noopener noreferrer"&gt;Flow Client Library&lt;/a&gt;, especially the authorization.&lt;/li&gt;
&lt;li&gt;Familiarize with &lt;a href="https://nftstorage.github.io/nft.storage/client/" rel="noopener noreferrer"&gt;NFT.storage documentation&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Last but not least, if you would like to contribute to make this tutorial better, start by creating an issue on the &lt;a href="https://github.com/protocol/nft-website/blob/main/docs/tutorial/flow-nft-marketplace.md" rel="noopener noreferrer"&gt;repo&lt;/a&gt; or just leave your comment. No contribution is too small.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building an NFT store on Flow : Part 1</title>
      <dc:creator>Pan Chasinga</dc:creator>
      <pubDate>Tue, 28 Dec 2021 16:58:03 +0000</pubDate>
      <link>https://dev.to/pancy/building-a-flow-nft-pet-store-part-1-4bn9</link>
      <guid>https://dev.to/pancy/building-a-flow-nft-pet-store-part-1-4bn9</guid>
      <description>&lt;p&gt;This tutorial will teach you how to create a simple NFT marketplace app on the &lt;a href="https://www.onflow.org/" rel="noopener noreferrer"&gt;Flow&lt;/a&gt; blockchain from scratch, using the Flow blockchain and IPFS/Filecoin storage via &lt;a href="https://nft.storage/" rel="noopener noreferrer"&gt;nft.storage&lt;/a&gt;. The finished project is a React app that lets you mint pet NFTs and query on-chain metadata and the photo of the pets:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frt6wobjpwaj3iutz3cpn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frt6wobjpwaj3iutz3cpn.png" alt="Flow NFT Pet store" width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The tutorial is broken into two parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;NFT and blockchain basic, understanding Flow and Cadence, and interacting with the smart contract using the Flow command line tool.&lt;/li&gt;
&lt;li&gt;Building a front-end React app and using the FCL library to interact with the smart contract.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;This is the first part of the tutorial.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;Although this tutorial is built for Flow blockchain, I am focusing on building up a general understanding of smart contracts and Non-fungible tokens (NFTs). If you have a working familiarity in JavaScript and React, but a passing familiarity with blockchains, you will be just fine catching up.&lt;/p&gt;

&lt;p&gt;If you are very new to the concept of smart contracts and NFTs, it's worth checking out this &lt;a href="https://nftschool.dev/concepts/non-fungible-tokens/" rel="noopener noreferrer"&gt;quick guide on NFT School&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up
&lt;/h2&gt;

&lt;p&gt;Before we begin, you will need to install a few things: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; and npm (comes with Node.js)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.onflow.org/cli/" rel="noopener noreferrer"&gt;Flow CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docker.com/compose/" rel="noopener noreferrer"&gt;Docker and Docker Compose&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You're free to use any code editor, but &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VSCode&lt;/a&gt; with &lt;a href="https://docs.onflow.org/vscode-extension/" rel="noopener noreferrer"&gt;Cadence Language support&lt;/a&gt; is a great option.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you will learn
&lt;/h2&gt;

&lt;p&gt;As we build a minimal version of the &lt;a href="https://github.com/jochasinga/flowwow/" rel="noopener noreferrer"&gt;Flowwow NFT pet store&lt;/a&gt;, you will learn the basic NFT building blocks from the ground up, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smart contracts with &lt;a href="https://docs.onflow.org/cadence/language/" rel="noopener noreferrer"&gt;Cadence Language&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;User wallet authentication&lt;/li&gt;
&lt;li&gt;Minting tokens and storing metadata on Filecoin/IPFS via &lt;a href="https://nft.storage/" rel="noopener noreferrer"&gt;NFT.storage&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Transferring tokens&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding ownership and resource
&lt;/h2&gt;

&lt;p&gt;A blockchain is a digital distributed ledger that tracks an &lt;em&gt;ownership&lt;/em&gt; of some &lt;em&gt;resource&lt;/em&gt;. There is nothing new about the ledger part—Your bank account is a ledger that keeps track of how much money you &lt;em&gt;own&lt;/em&gt; and how much is spent (change of ownership) at any time. The key components to a ledger are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.toresource"&gt;Resource&lt;/a&gt; at play. In this case a currency.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.toaccounts"&gt;Accounts&lt;/a&gt; to own the resource, or the access to it.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.tocontract"&gt;Contract&lt;/a&gt; or a ruleset to govern the economy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Resource
&lt;/h3&gt;

&lt;p&gt;A resource can be any &lt;em&gt;thing&lt;/em&gt; — from currency, crop, to digital monster — as long as the type of resource is agreed upon commonly by all accounts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accounts
&lt;/h3&gt;

&lt;p&gt;Each account owns a ledger of its own to keep track of the spending (transferring) and imbursing (receiving) of the resource.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contract
&lt;/h3&gt;

&lt;p&gt;A contract is a ruleset governing how the "game" is played. Accounts that break the ruleset may be punished in some way. Normally, it is a central authority like a bank who creates this contract for all accounts.&lt;/p&gt;

&lt;p&gt;Because the conventional ledgers are owned and managed by a trusted authority like your bank, when you transfer the ownership of a few dollars (&lt;code&gt;-$4.00&lt;/code&gt;) to buy a cup of coffee from Mr. Peet, the bank needs to be consistent and update the ledgers on both sides to reflect the ownership change (Peet has &lt;code&gt;+$4.00&lt;/code&gt; and you have &lt;code&gt;-$4.00&lt;/code&gt;). Because both ledgers are not openly visible to both of Peet and you and the the currency is likely digital, there is no guarantee that the bank won't mistakenly or intentionally update either ledger with the incorrect value.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Your bank probably owes you&lt;/strong&gt;&lt;br&gt;
If you have a saving account with some money in it, you might be loaning your money to your bank. You are trusting it to have your money for you when you want to withdraw. This is why if you had a billion dollars in your account and you want to withdraw today, your teller will freak out. Your money is just part of the stream of digital currency your bank is free to do anything with.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What is interesting about the blockchain is the distributed part. Because there is only a single, open &lt;em&gt;decentralized&lt;/em&gt; ledger, there is no central authority (like a bank) for you to trust with bookkeeping. In fact, there is no need for you to trust anyone at all. You only need to trust the copy of the software run by other computers in the network to uphold the legitimacy of the book. Moreover, it is very hard for one (or more) of the computers to run an altered version of that software to bend the rule.&lt;/p&gt;

&lt;p&gt;A good analogy is an umpire-less tennis game where any dispute (like determining if the ball lands in the court) is distributed to all the audience to judge. Meanwhile, these audience members are also participating in the game, with the stake that makes them lose if they judge wrongly. This way, any small inconsistencies are likely caught and rejected fair and square. You are no longer trusting your bank. The eternal flow of ownerships hence becomes &lt;em&gt;trustless&lt;/em&gt; because everyone is doing what's best for themselves.&lt;/p&gt;

&lt;p&gt;"Why such emphasis on ownership?" you may ask. This was leading to the concept of resource ownership baked right into the smart contract in Flow. Learning to visualize everything as resources will help in getting up to speed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick tour of Cadence
&lt;/h2&gt;

&lt;p&gt;Like Solidity language for Ethereum, Flow uses &lt;a href="https://docs.onflow.org/cadence/language/" rel="noopener noreferrer"&gt;Cadence Language&lt;/a&gt; for smart contracts, transactions, and scripts. Inspired by the &lt;a href="https://rust-lang.org/" rel="noopener noreferrer"&gt;Rust&lt;/a&gt; and &lt;a href="https://move-book.com/" rel="noopener noreferrer"&gt;Move&lt;/a&gt; languages, the interpreter tracks when a resource is being &lt;em&gt;moved&lt;/em&gt; from a variable to the next and makes sure it can never be mutually accessible in the program.&lt;/p&gt;

&lt;p&gt;The three types of Cadence program you will be writing are &lt;a href="https://docs.onflow.org/cadence/language/contracts/#gatsby-focus-wrapper" rel="noopener noreferrer"&gt;contracts&lt;/a&gt;, &lt;a href="https://docs.onflow.org/cadence/language/transactions/#gatsby-focus-wrapper" rel="noopener noreferrer"&gt;transactions&lt;/a&gt;, and &lt;a href="https://docs.onflow.org/fcl/reference/scripts/" rel="noopener noreferrer"&gt;scripts&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contract
&lt;/h3&gt;

&lt;p&gt;A contract is an initial program that gets deployed to the blockchain, initiating the logic for your app and allowing access to resources you create and the capabilities that come with them.&lt;/p&gt;

&lt;p&gt;Two of the most common constructs in a contract are &lt;strong&gt;resources&lt;/strong&gt; and &lt;strong&gt;interfaces&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Resources
&lt;/h4&gt;

&lt;p&gt;Resources are items stored in user accounts that are accessible&lt;br&gt;
through access control measures defined in the contract. They are usually the assets being tracked or some capabilities, such as a capability to withdraw an asset from an account. They are akin to classes or structs in some languages. Resources can only be in one place at a time, and they are said to be &lt;em&gt;moved&lt;/em&gt; rather than &lt;em&gt;assigned&lt;/em&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  Interfaces
&lt;/h4&gt;

&lt;p&gt;Interfaces define the behaviors or capabilities of resources. They are akin to interfaces in some languages. They are usually implemented by other resources. Interfaces are also defined with the keyword &lt;code&gt;resource&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here is an example of an &lt;code&gt;NFT&lt;/code&gt; resource and an &lt;code&gt;Ownable&lt;/code&gt; interface (à la &lt;a href="https://docs.openzeppelin.com/contracts/3.x/api/token/erc721" rel="noopener noreferrer"&gt;ERC721&lt;/a&gt;) in a separate &lt;code&gt;PetShop&lt;/code&gt; contract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;PetShop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// A map recording owners of NFTs&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;owners&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;UInt64&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// A Transferrable interface declaring some methods or "capabilities"&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;Transferrable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;
      &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;transferTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;recipient&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// NFT resource implements Transferrable&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="n"&gt;NFT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Transferrable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// Unique id for each NFT.&lt;/span&gt;
        &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UInt64&lt;/span&gt;

        &lt;span class="c1"&gt;// Constructor method&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;initId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;initId&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="n"&gt;Address&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;owners&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.id&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="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;transferTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;recipient&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Code to transfer this NFT resource to the recipient's address.&lt;/span&gt;
        &lt;span class="p"&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;Note the access modifier &lt;code&gt;pub&lt;/code&gt; before each definition. This declares public access for all user accounts. Writing a Cadence contract revolves around designing access control.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transaction
&lt;/h3&gt;

&lt;p&gt;Transactions tell the on-chain contract to change the state of the chain. Like Ethereum, the change is synchronized throughout the peers and become permanent. Because it takes computing power from many computers to do so, a transaction is considered a &lt;em&gt;write&lt;/em&gt; operation that incurs a gas fee to be paid to the network. Transactions require one or more accounts to sign and authorize. For instance, minting and transferring tokens are transactions.&lt;/p&gt;

&lt;p&gt;Here is an example of a transaction which requires a current account's signature to sign an action and mutate the chain's state. In this case, it is just logging "Hello, transaction", which would be a waste of resource.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;transaction&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Takes the signing account as a single argument.&lt;/span&gt;
    &lt;span class="nf"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AuthAccount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// This is where you write code that requires a &lt;/span&gt;
        &lt;span class="c1"&gt;// signature, such as withdrawing a token from the &lt;/span&gt;
        &lt;span class="c1"&gt;// signing account.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;execute&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// This is where you write code that does not require &lt;/span&gt;
        &lt;span class="c1"&gt;// a signature.&lt;/span&gt;
        &lt;span class="k"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, transaction"&lt;/span&gt;&lt;span class="p"&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;h3&gt;
  
  
  Script
&lt;/h3&gt;

&lt;p&gt;Scripts are Cadence programs that are run &lt;strong&gt;on the client&lt;/strong&gt; to &lt;em&gt;read&lt;/em&gt; the state of the chain. Therefore, they do not incur any gas fee and do not need an account to sign them. A common use case is a blockchain explorer that queries the state of the chain.&lt;/p&gt;

&lt;p&gt;Here is an example of a script reading an NFT's current owner's address by accessing the on-chain &lt;code&gt;owners&lt;/code&gt; map by the token's ID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Takes a target token ID as a parameter and returns an &lt;/span&gt;
&lt;span class="c1"&gt;// address of the current owner.&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&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;PetStore&lt;/span&gt;&lt;span class="py"&gt;.owner&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;id&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nevermind if you don't understand the syntax. As long as you understand the overall steps and recognize the similarities to another language, you will be fine. We will talk more about Cadence's syntax later.&lt;/p&gt;

&lt;p&gt;Both transactions and scripts are invoked on the client side, usually with the help of a command line tool or JavaScript library, both of which will be covered in this tutorial series.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building pet store
&lt;/h2&gt;

&lt;p&gt;Now that we had a glance at Cadence, the smart contract language, we are ready to start building some of the features for our NFT pet store.&lt;/p&gt;

&lt;p&gt;We will create and prepare a project structure for our React app for the second part. Make sure you already have the tools(#set-up) installed.&lt;/p&gt;

&lt;p&gt;Now, create a new React app by typing the following commands in your shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-react-app petstore&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;petstore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then, initialize a Flow project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flow init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see a new React project created with a &lt;code&gt;flow.json&lt;/code&gt; configuration file inside. This file is important as it tells the command line tool and the FCL library where to find things in the project. Let's take a closer look at the newly created directory and add some configurations to the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project structure
&lt;/h3&gt;

&lt;p&gt;First of all, note the &lt;code&gt;flow.json&lt;/code&gt; file under the root directory. This configuration file was created when we typed the command &lt;code&gt;flow init&lt;/code&gt; and tells Flow that this is a Flow project. We will leave most of the initial settings as they were, but make sure it contains these fields by adding or changing them accordingly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nl"&gt;"contracts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"PetStore"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./src/flow/contracts/PetStore.cdc"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nl"&gt;"deployments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"emulator"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"emulator-account"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"PetStore"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These fields tell Flow where to look for the contract and the accounts related to the project so we will be able to run the command line to deploy it to the blockchain. Note that we are opting for an emulator account, which is a local blockchain emulator. &lt;/p&gt;

&lt;p&gt;Now we will need to create some directories for our Cadence code.&lt;/p&gt;

&lt;p&gt;Create a directory named &lt;code&gt;flow&lt;/code&gt; under &lt;code&gt;src&lt;/code&gt; directory, and create three more subdirectories named &lt;code&gt;contract&lt;/code&gt;, &lt;code&gt;transaction&lt;/code&gt;, and &lt;code&gt;script&lt;/code&gt; under &lt;code&gt;flow&lt;/code&gt;, respectively. This can be combined into a single command (make sure your current directory is &lt;code&gt;petstore&lt;/code&gt; before running this):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; src/flow/&lt;span class="o"&gt;{&lt;/span&gt;contract,transaction,script&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you might have guessed, each directory will contain the corresponding Cadence code for each type of interaction.&lt;/p&gt;

&lt;p&gt;Now, in each of these directories, create a Cadence file with the following names: &lt;code&gt;contract/PetStore.cdc&lt;/code&gt;, &lt;code&gt;transaction/MintToken.cdc&lt;/code&gt;, and &lt;code&gt;script/GetTokenIds.cdc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;src&lt;/code&gt; directory should now look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
|— flow
|   |— contract
|   |   |
|   |   &lt;span class="sb"&gt;`&lt;/span&gt;— PetStore.cdc
|   |— script
|   |   |
|   |   &lt;span class="sb"&gt;`&lt;/span&gt;— GetTokenIds.cdc
|   &lt;span class="sb"&gt;`&lt;/span&gt;— transaction
|       |
|       &lt;span class="sb"&gt;`&lt;/span&gt;— MintToken.cdc
|
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;PetStore&lt;/code&gt; contract
&lt;/h3&gt;

&lt;p&gt;it is about time we write our smart contract. It is the most involved code in this project, so it is the ideal place to learn the language.&lt;/p&gt;

&lt;p&gt;First, create the contract block that defines an &lt;code&gt;NFT&lt;/code&gt; resource within:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;PetStore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// This dictionary stores token owners' addresses.&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;owners&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="n"&gt;NFT&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// The Unique ID for each token, starting from 1.&lt;/span&gt;
        &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UInt64&lt;/span&gt;

        &lt;span class="c1"&gt;// String -&amp;gt; String dictionary to hold &lt;/span&gt;
        &lt;span class="c1"&gt;// token's metadata.&lt;/span&gt;
        &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// The NFT's constructor. All declared variables are&lt;/span&gt;
        &lt;span class="c1"&gt;// required to be initialized here.&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;
        &lt;span class="p"&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;Note that we have declared a &lt;a href="https://docs.onflow.org/cadence/language/values-and-types/#dictionaries" rel="noopener noreferrer"&gt;Dictionary&lt;/a&gt; and stored it in a variable named &lt;code&gt;owners&lt;/code&gt;. This dictionary has the type &lt;code&gt;{UInt64: Address}&lt;/code&gt; which maps &lt;a href="https://docs.onflow.org/cadence/language/values-and-types/#integers" rel="noopener noreferrer"&gt;unsigned 64-bit integers&lt;/a&gt; to users' &lt;a href="https://docs.onflow.org/cadence/language/values-and-types/#addresses" rel="noopener noreferrer"&gt;Addresses&lt;/a&gt;. We will use &lt;code&gt;owners&lt;/code&gt; to keep track of all the current owners of all tokens globally.&lt;/p&gt;

&lt;p&gt;Also note that the &lt;code&gt;owners&lt;/code&gt; variable is prepended by a &lt;code&gt;var&lt;/code&gt; keyword, while the &lt;code&gt;id&lt;/code&gt; variable is prepended by a &lt;code&gt;let&lt;/code&gt; keyword. In Cadence, a mutable variable is defined using &lt;code&gt;var&lt;/code&gt; while an immutable one is defined with &lt;code&gt;let&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Immutable vs mutable&lt;/strong&gt;&lt;br&gt;
In Cadence, a variable stores a mutable variable that can be changed later in the program while a &lt;em&gt;binding&lt;/em&gt; binds an immutable value that cannot be changed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the body of &lt;code&gt;NFT&lt;/code&gt; resource, we declare &lt;code&gt;id&lt;/code&gt; field and a constructor method to assign the &lt;code&gt;id&lt;/code&gt; to the &lt;code&gt;NFT&lt;/code&gt; instance.&lt;/p&gt;

&lt;p&gt;Now we are ready to move on to the next step.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;NFTReceiver&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Now, we will add the &lt;code&gt;NFTReceiver&lt;/code&gt; interface to define the &lt;em&gt;capabilities&lt;/em&gt; of a &lt;em&gt;receiver of NFTs&lt;/em&gt;. What this means is only the accounts with these capabilities can receive tokens from another addresses.&lt;/p&gt;

&lt;p&gt;To reiterate, an interface is &lt;em&gt;not&lt;/em&gt; an instance of an object, like a user account. It is a set of behaviors that a resource can implement to become capable of performing certain actions, for example withdrawing and depositing tokens.&lt;/p&gt;

&lt;p&gt;Add the following &lt;code&gt;NFTReceiver&lt;/code&gt; code to the existing &lt;code&gt;PetStore&lt;/code&gt; contract. I will begin the comment for each method with "can" to make this clear that we are talking about a capability. Moreover, we won't be displaying all the code written previously. Instead, Comments with ellipses &lt;code&gt;...&lt;/code&gt; will be used to notate these truncated code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;PetStore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;NFTReceiver&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// Can withdraw a token by its ID and returns &lt;/span&gt;
        &lt;span class="c1"&gt;// the token.&lt;/span&gt;
        &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;NFT&lt;/span&gt;

        &lt;span class="c1"&gt;// Can deposit an NFT to this NFTReceiver.&lt;/span&gt;
        &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;NFT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// Can fetch all NFT IDs belonging to this &lt;/span&gt;
        &lt;span class="c1"&gt;// NFTReceiver.&lt;/span&gt;
        &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getTokenIds&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="c1"&gt;// Can fetch the metadata of an NFT instance &lt;/span&gt;
        &lt;span class="c1"&gt;// by its ID.&lt;/span&gt;
        &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getTokenMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Can update the metadata of an NFT.&lt;/span&gt;
        &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;updateTokenMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&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;Let's go over each method together.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;withdraw(id: UInt64): @NFT&lt;/code&gt; method takes an NFT's &lt;code&gt;id&lt;/code&gt;, withdraws a token of type &lt;code&gt;@NFT&lt;/code&gt;, which is prepended with a &lt;code&gt;@&lt;/code&gt; to indicate a reference to a resource.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;deposit(token: @NFT)&lt;/code&gt; method takes a token reference and deposits to the current &lt;code&gt;NFTReceiver&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;getTokenIds(): [UInt64]&lt;/code&gt; method accesses all token IDs owned by the current &lt;code&gt;NFTReceiver&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;getTokenMetadata(id: UInt64) : {String : String}&lt;/code&gt; method takes a token ID, reads the metadata, and returns it as a dictionary.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;updateTokenMetadata(id: UInt64, metadata: {String: String})&lt;/code&gt; method takes an ID of an &lt;code&gt;NFT&lt;/code&gt; and a metadata dictionary to update the target NFT's metadata.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;NFTCollection&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Now let's create an &lt;code&gt;NFTCollection&lt;/code&gt; resource to implement the &lt;code&gt;NFTReceiver&lt;/code&gt; interface. Think of this as a "vault" where NFTs can be deposited or withdrawn.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;PetStore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// ... The @NFT code ...&lt;/span&gt;

    &lt;span class="c1"&gt;// ... The @NFTReceiver code ...&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="n"&gt;NFTCollection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;NFTReceiver&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// Keeps track of NFTs this collection.&lt;/span&gt;
        &lt;span class="nf"&gt;access&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;ownedNFTs&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="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;NFT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Constructor&lt;/span&gt;
        &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.ownedNFTs&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Destructor&lt;/span&gt;
        &lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;destroy&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.ownedNFTs&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Withdraws and return an NFT token.&lt;/span&gt;
        &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;NFT&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.ownedNFTs&lt;/span&gt;&lt;span class="nf"&gt;.remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="nd"&gt;token!&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Deposits a token to this NFTCollection instance.&lt;/span&gt;
        &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;NFT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.ownedNFTs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-!&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Returns an array of the IDs that are in this collection.&lt;/span&gt;
        &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getTokenIds&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.ownedNFTs.keys&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Returns the metadata of an NFT based on the ID.&lt;/span&gt;
        &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getTokenMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.ownedNFTs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="py"&gt;.metadata&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nd"&gt;metadata!&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Updates the metadata of an NFT based on the ID.&lt;/span&gt;
        &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;updateTokenMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&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;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="py"&gt;.keys&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.ownedNFTs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="py"&gt;.metadata&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&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="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Public factory method to create a collection&lt;/span&gt;
    &lt;span class="c1"&gt;// so it is callable from the contract scope.&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;createNFTCollection&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;NFTCollection&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="nf"&gt;NFTCollection&lt;/span&gt;&lt;span class="p"&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;That's a handful of new code. It will soon become natural to you with patience.&lt;/p&gt;

&lt;p&gt;First we declare a mutable dictionary and store it in a variable named &lt;code&gt;ownedNFTs&lt;/code&gt;. Note the new access modifier &lt;code&gt;pub(set)&lt;/code&gt;, which gives public write access to the users.&lt;/p&gt;

&lt;p&gt;This dictionary stores the NFTs for this collection by mapping the ID to NFT resource. Note that because the dictionary stores &lt;code&gt;@NFT&lt;/code&gt; resources, we prepend the type with &lt;code&gt;@&lt;/code&gt;, making itself a resource too.&lt;/p&gt;

&lt;p&gt;In the contructor method, &lt;code&gt;init()&lt;/code&gt;, we instantiate the &lt;code&gt;ownedNFTs&lt;/code&gt; with an empty dictionary. A resource also needs a &lt;code&gt;destroy()&lt;/code&gt; destructor method to make sure it is being freed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Nested Resource&lt;/strong&gt;&lt;br&gt;
A &lt;a href="https://docs.onflow.org/cadence/language/composite-types/" rel="noopener noreferrer"&gt;composite structure&lt;/a&gt; including a dictionary can store resources, but when they do they will be treated as resources. Which means they need to be &lt;em&gt;moved&lt;/em&gt; rather than &lt;em&gt;assigned&lt;/em&gt; and their type will be annotated with &lt;code&gt;@&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;code&gt;withdraw(id: UInt64): @NFT&lt;/code&gt; method removes an NFT from the collection's &lt;code&gt;ownedNFTs&lt;/code&gt; array and return it.&lt;/p&gt;

&lt;p&gt;The left-pointing arrow &lt;code&gt;&amp;lt;-&lt;/code&gt; is known as a &lt;em&gt;move&lt;/em&gt; symbol, and we use it to move a resource around. Once a resource has been moved, it can no longer be used from the old variable.&lt;/p&gt;

&lt;p&gt;Note the &lt;code&gt;!&lt;/code&gt; symbol after the &lt;code&gt;token&lt;/code&gt; variable. It &lt;a href="https://docs.onflow.org/cadence/language/values-and-types/#force-unwrap-" rel="noopener noreferrer"&gt;force-unwraps&lt;/a&gt; the &lt;code&gt;Optional&lt;/code&gt; value. If the value turns out to be &lt;code&gt;nil&lt;/code&gt;, the program panics and crashes.&lt;/p&gt;

&lt;p&gt;Because resources are core to Cadence, their types are annotated with a &lt;code&gt;@&lt;/code&gt; to make them explicit. For instance, &lt;code&gt;@NFT&lt;/code&gt; and &lt;code&gt;@NFTCollection&lt;/code&gt; are two resource types.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;deposit(token: @NFT)&lt;/code&gt; function takes the &lt;code&gt;@NFT&lt;/code&gt; resource as a parameter and stores it in the &lt;code&gt;ownedNFTs&lt;/code&gt; array in this &lt;code&gt;@NFTCollection&lt;/code&gt; instance.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;!&lt;/code&gt; symbol reappears here, but now it's after the move arrow &lt;code&gt;&amp;lt;-!&lt;/code&gt;. This is called a &lt;a href="https://docs.onflow.org/cadence/language/values-and-types/#force-assignment-operator%E2%80%94" rel="noopener noreferrer"&gt;force-move or force-assign&lt;/a&gt; operator, which only moves a resource to a variable if the variable is &lt;code&gt;nil&lt;/code&gt;. Otherwise, the program panics.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;getTokenIds(): [UInt64]&lt;/code&gt; method simply reads all the &lt;code&gt;UInt64&lt;/code&gt; keys of the &lt;code&gt;ownedNFTs&lt;/code&gt; dictionary and returns them as an array.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;getTokenMetadata(id: UInt64): {String : String}&lt;/code&gt; method reads the &lt;code&gt;metadata&lt;/code&gt; field of an &lt;code&gt;@NFT&lt;/code&gt; stored by its ID in the &lt;code&gt;ownedNFTs&lt;/code&gt; dictionary and returns it.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;updateTokenMetadata(id: UInt64, metadata: {String: String})&lt;/code&gt; method is a bit more involved.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="py"&gt;.keys&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.ownedNFTs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="py"&gt;.metadata&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the body of the method, we loop over all the keys of the given metadata, inserting into the current metadata dictionary the new value. Note the &lt;code&gt;?&lt;/code&gt; in the call chain. It is used with &lt;code&gt;Optional&lt;/code&gt;s values to keep going down the call chain only if the value is not &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We have successfully implemented the &lt;code&gt;@NFTReceiver&lt;/code&gt; interface for the &lt;code&gt;@NFTCollection&lt;/code&gt; resource.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;NFTMinter&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The last and very important component for our &lt;code&gt;PetStore&lt;/code&gt; contract is &lt;code&gt;@NFTMinter&lt;/code&gt; resource, which will contain an exclusive code for the contract owner to mint all the tokens. Without it, our store will not be able to mint any pet tokens. It is very simplistic though, since we have already blazed through the more complex components. Its only &lt;code&gt;mint(): @NFT&lt;/code&gt; method creates an &lt;code&gt;@NFT&lt;/code&gt; resource, gives it an ID, saves the address of the first owner to the contract (which is the address of the contract owner, although you could change it to mint and transfer to the creator's address in one step), increments the universal ID counter, and returns the new token.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;PetStore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// ... NFT code ...&lt;/span&gt;

    &lt;span class="c1"&gt;// ... NFTReceiver code ...&lt;/span&gt;

    &lt;span class="c1"&gt;// ... NFTCollection code ...&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="n"&gt;NFTMinter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// Declare a global variable to count ID.&lt;/span&gt;
        &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;idCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UInt64&lt;/span&gt;

        &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Instantialize the ID counter.&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.idCount&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="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;mint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;}):&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;NFT&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="c1"&gt;// Create a new @NFT resource with the current ID.&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="nf"&gt;NFT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.idCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;// Save the current owner's address to the dictionary.&lt;/span&gt;
            &lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.owners&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.idCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.account.address&lt;/span&gt;

            &lt;span class="c1"&gt;// Increment the ID&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.idCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.idCount&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;UInt64&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;
        &lt;span class="p"&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;By now, we have all the nuts and bolts we need for the contract. The only thing that is missing is a way to initialize this contract at deployment time. Let's create a constructor method to create an empty &lt;code&gt;@NFTCollection&lt;/code&gt; instance for the deployer of the contract (you) so it is possible for the contract owner to mint and store NFTs from the contract. As we go over this last hurdle, we will also learn about the other important concept in Cadence—&lt;a href="https://docs.onflow.org/cadence/tutorial/02-hello-world/#account-filesystem-domain-structure-where-can-i-store-my-stuff" rel="noopener noreferrer"&gt;Storage and domains&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;PetStore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// ... @NFT code ...&lt;/span&gt;

    &lt;span class="c1"&gt;// ... @NFTReceiver code ...&lt;/span&gt;

    &lt;span class="c1"&gt;// ... @NFTCollection code ...&lt;/span&gt;

    &lt;span class="c1"&gt;// This contract constructor is called once when the contract is deployed.&lt;/span&gt;
    &lt;span class="c1"&gt;// It does the following:&lt;/span&gt;
    &lt;span class="c1"&gt;//&lt;/span&gt;
    &lt;span class="c1"&gt;// - Creating an empty Collection for the deployer of the collection so&lt;/span&gt;
    &lt;span class="c1"&gt;//   the owner of the contract can mint and own NFTs from that contract.&lt;/span&gt;
    &lt;span class="c1"&gt;//&lt;/span&gt;
    &lt;span class="c1"&gt;// - The `Collection` resource is published in a public location with reference&lt;/span&gt;
    &lt;span class="c1"&gt;//   to the `NFTReceiver` interface. This is how we tell the contract that the functions defined&lt;/span&gt;
    &lt;span class="c1"&gt;//   on the `NFTReceiver` can be called by anyone.&lt;/span&gt;
    &lt;span class="c1"&gt;//&lt;/span&gt;
    &lt;span class="c1"&gt;// - The `NFTMinter` resource is saved in the account storage for the creator of&lt;/span&gt;
    &lt;span class="c1"&gt;//   the contract. Only the creator can mint tokens.&lt;/span&gt;
    &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Set `owners` to an empty dictionary.&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.owners&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

        &lt;span class="c1"&gt;// Create a new `@NFTCollection` instance and save it in `/storage/NFTCollection` domain,&lt;/span&gt;
        &lt;span class="c1"&gt;// which is only accessible by the contract owner's account.&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.account&lt;/span&gt;&lt;span class="nf"&gt;.save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="nf"&gt;NFTCollection&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;NFTCollection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// "Link" only the `@NFTReceiver` interface from the `@NFTCollection` stored at `/storage/NFTCollection` domain to the `/public/NFTReceiver` domain, which is accessible to any user.&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.account.link&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;NFTReceiver&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;public&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;NFTReceiver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;NFTCollection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// Create a new `@NFTMinter` instance and save it in `/storage/NFTMinter` domain, accesible&lt;/span&gt;
        &lt;span class="c1"&gt;// only by the contract owner's account.&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.account&lt;/span&gt;&lt;span class="nf"&gt;.save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="nf"&gt;NFTMinter&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;NFTMinter&lt;/span&gt;&lt;span class="p"&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;Hopefully, the high-level steps are clear to you after you have followed through the comments. We will talk about domains briefly here. Domains are general-purpose storages accessible to Flow accounts commonly used for storing resources. Intuitively, they are similar to common filesystems. There are three domain namespaces in Cadence:&lt;/p&gt;

&lt;h4&gt;
  
  
  /storage
&lt;/h4&gt;

&lt;p&gt;This namespace can only be accessed by the owner of the account.&lt;/p&gt;

&lt;h4&gt;
  
  
  /private
&lt;/h4&gt;

&lt;p&gt;This namespace is used to stored private objects and &lt;a href="https://docs.onflow.org/cadence/language/capability-based-access-control/" rel="noopener noreferrer"&gt;capabilities&lt;/a&gt; whose access can be granted to selected accounts.&lt;/p&gt;

&lt;h4&gt;
  
  
  /public
&lt;/h4&gt;

&lt;p&gt;This namespace is accessible by all accounts that interact with the contract.&lt;/p&gt;

&lt;p&gt;In our previous code, we created an &lt;code&gt;@NFTCollection&lt;/code&gt; instance for our own account and saved it to the &lt;code&gt;/storage/NFTCollection&lt;/code&gt; namespace. The path following the first namespace is arbitrary, so we could have named it &lt;code&gt;/storage/my/nft/collection&lt;/code&gt;. Then, something odd happened as we "link" a &lt;a href="https://docs.onflow.org/cadence/language/" rel="noopener noreferrer"&gt;reference&lt;/a&gt; to the &lt;code&gt;@NFTReceiver&lt;/code&gt; capability from the &lt;code&gt;/storage&lt;/code&gt; domain to &lt;code&gt;/public&lt;/code&gt;. The caret pair &lt;code&gt;&amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;gt;&lt;/code&gt; was used to explicitly annotate the type of the reference being linked, &lt;code&gt;&amp;amp;{NFTReceiver}&lt;/code&gt;, with the &lt;code&gt;&amp;amp;&lt;/code&gt; and the wrapping brackets &lt;code&gt;{&lt;/code&gt; and &lt;code&gt;}&lt;/code&gt; to define the &lt;em&gt;unauthorized reference&lt;/em&gt; type (see &lt;a href="https://docs.onflow.org/cadence/language/" rel="noopener noreferrer"&gt;References&lt;/a&gt; to learn more). Last but not least, we created the &lt;code&gt;@NFTMinter&lt;/code&gt; instance and saved it to our account's &lt;code&gt;/storage/NFTMinter&lt;/code&gt; domain.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For a deep dive into storages, check out &lt;a href="https://docs.onflow.org/cadence/tutorial/02-hello-world/#account-filesystem-domain-structure-where-can-i-store-my-stuff" rel="noopener noreferrer"&gt;Account Storage&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As we wrap up our &lt;code&gt;PetStore&lt;/code&gt; contract, let's try to deploy it to the Flow emulator to verify the contract. Start the emulator by typing &lt;code&gt;flow emulator&lt;/code&gt; in your shell.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flow emulator

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; INFO[0000] ⚙️   Using service account 0xf8d6e0586b0a20c7  &lt;span class="nv"&gt;serviceAddress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;f8d6e0586b0a20c7 &lt;span class="nv"&gt;serviceHashAlgo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;SHA3_256 &lt;span class="nv"&gt;servicePrivKey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bd7a891abd496c9cf933214d2eab26b2a41d614d81fc62763d2c3f65d33326b0 &lt;span class="nv"&gt;servicePubKey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5f5f1442afcf0c817a3b4e1ecd10c73d151aae6b6af74c0e03385fb840079c2655f4a9e200894fd40d51a27c2507a8f05695f3fba240319a8a2add1c598b5635 &lt;span class="nv"&gt;serviceSigAlgo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ECDSA_P256
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; INFO[0000] 📜  Flow contracts                             &lt;span class="nv"&gt;FlowFees&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0xe5a8b7f23e8b548f &lt;span class="nv"&gt;FlowServiceAccount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0xf8d6e0586b0a20c7 &lt;span class="nv"&gt;FlowStorageFees&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0xf8d6e0586b0a20c7 &lt;span class="nv"&gt;FlowToken&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0x0ae53cb6e3f42a79 &lt;span class="nv"&gt;FungibleToken&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0xee82856bf20e2aa6
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; INFO[0000] 🌱  Starting gRPC server on port 3569          &lt;span class="nv"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3569
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; INFO[0000] 🌱  Starting HTTP server on port 8080          &lt;span class="nv"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take note of the &lt;strong&gt;FlowServiceAccount&lt;/strong&gt; address, which is a hexadecimal number &lt;code&gt;0xf8d6e0586b0a20c7&lt;/code&gt; (In fact, these numbers are so ubiquitous in Flow that it has its own &lt;a href="https://docs.onflow.org/cadence/language/values-and-types/#addresses" rel="noopener noreferrer"&gt;&lt;code&gt;Address&lt;/code&gt;&lt;/a&gt; type). This is the address of the contract on the emulator.&lt;/p&gt;

&lt;p&gt;Open up a new shell, making sure you are inside the project directory, then type &lt;code&gt;flow project deploy&lt;/code&gt; to deploy our first contract. You should see an output similar to this if it was successful:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flow project deploy

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Deploying 1 contracts &lt;span class="k"&gt;for &lt;/span&gt;accounts: emulator-account
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; PetStore -&amp;gt; 0xf8d6e0586b0a20c7 &lt;span class="o"&gt;(&lt;/span&gt;11e3afe90dc3a819ec9736a0a36d29d07a2f7bca856ae307dcccf4b455788710&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ✨ All contracts deployed successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations! You have learned how to write and deploy your first smart contract.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Oops! That didn't work&lt;/strong&gt;&lt;br&gt;
Check &lt;code&gt;flow.json&lt;/code&gt; configuration and make sure the path to the contract is correct.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;MintToken&lt;/code&gt; transaction
&lt;/h3&gt;

&lt;p&gt;The first and most important transaction for &lt;em&gt;any&lt;/em&gt; NFT app is perhaps the one that mints tokens into existence! Without it there won't be any cute tokens to sell and trade. So let's start coding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// MintToken.cdc&lt;/span&gt;

&lt;span class="c1"&gt;// Import the `PetStore` contract instance from the master account address.&lt;/span&gt;
&lt;span class="c1"&gt;// This is a fixed address for used with the emulator only.&lt;/span&gt;
&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PetStore&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="mi"&gt;0xf8d6e0586b0a20c7&lt;/span&gt;

&lt;span class="nf"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Declare an "unauthorized" reference to `NFTReceiver` interface.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;receiverRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.NFTReceiver&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Declare an "authorized" reference to the `NFTMinter` interface.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;minterRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.NFTMinter&lt;/span&gt;

    &lt;span class="c1"&gt;// `prepare` block always take one or more `AuthAccount` parameter(s) to indicate&lt;/span&gt;
    &lt;span class="c1"&gt;// who are signing the transaction.&lt;/span&gt;
    &lt;span class="c1"&gt;// It takes the account info of the user trying to execute the transaction and&lt;/span&gt;
    &lt;span class="c1"&gt;// validate. In this case, the contract owner's account.&lt;/span&gt;
    &lt;span class="c1"&gt;// Here we try to "borrow" the capabilities available on `NFTMinter` and `NFTReceiver`&lt;/span&gt;
    &lt;span class="c1"&gt;// resources, and will fail if the user executing this transaction does not have access&lt;/span&gt;
    &lt;span class="c1"&gt;// to these resources.&lt;/span&gt;
    &lt;span class="nf"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AuthAccount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// Note that we have to call `getCapability(_ domain: Domain)` on the account&lt;/span&gt;
        &lt;span class="c1"&gt;// object before we can `borrow()`.&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.receiverRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="py"&gt;.getCapability&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.NFTReceiver&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;public&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;NFTReceiver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.borrow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nf"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not borrow receiver reference"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// With an authorized reference, we can just `borrow()` it.&lt;/span&gt;
        &lt;span class="c1"&gt;// Note that `NFTMinter` is borrowed from `/storage` domain namespace, which&lt;/span&gt;
        &lt;span class="c1"&gt;// means it is only accessible to this account.&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.minterRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="py"&gt;.borrow&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.NFTMinter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;NFTMinter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nf"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not borrow minter reference"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// `execute` block executes after the `prepare` block is signed and validated.&lt;/span&gt;
    &lt;span class="n"&gt;execute&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Mint the token by calling `mint(metadata: {String: String})` on `@NFTMinter` resource, which returns an `@NFT` resource, and move it to a variable `newToken`.&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;newToken&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.minterRef&lt;/span&gt;&lt;span class="nf"&gt;.mint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// Call `deposit(token: @NFT)` on the `@NFTReceiver` resource to deposit the token.&lt;/span&gt;
        &lt;span class="c1"&gt;// Note that this is where the metadata can be changed before transferring.&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.receiverRef&lt;/span&gt;&lt;span class="nf"&gt;.deposit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;newToken&lt;/span&gt;&lt;span class="p"&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;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Ambiguous type warning&lt;/strong&gt;&lt;br&gt;
If you are using VSCode, chances are you might see the editor flagging the&lt;br&gt;
lines referring to &lt;code&gt;PetStore.NFTReceiver&lt;/code&gt; and &lt;code&gt;PetStore.NFTMinter&lt;/code&gt; types&lt;br&gt;
with an "ambiguous type &amp;lt;T&amp;gt; not found". Try to reset the running emulator&lt;br&gt;
by pressing &lt;code&gt;Ctrl+C&lt;/code&gt; in the shell where you ran the emulator to interrupt it&lt;br&gt;
and run it again with &lt;code&gt;flow emulator&lt;/code&gt; and on a different shell, don't forget&lt;br&gt;
to redeploy the contract with &lt;code&gt;flow project deploy&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first line of the transaction code imports the &lt;code&gt;PetStore&lt;/code&gt; contract instance.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;transaction&lt;/code&gt; block takes an arbitrary number of named parameters, which will be provided by the calling program (In Flow CLI, JavaScript, Go, or other language). These parameters are the only channels for the transaction code to interact with the outside world.&lt;/p&gt;

&lt;p&gt;Next, we declare references &lt;code&gt;&amp;amp;{NFTReceiver}&lt;/code&gt; and &lt;code&gt;&amp;amp;NFTMinter&lt;/code&gt; (Note the first is an unauthorized reference).&lt;/p&gt;

&lt;p&gt;Now we enter the &lt;code&gt;prepare&lt;/code&gt; block, which is responsible for authorizing the transaction. This block takes an argument of type &lt;code&gt;AuthAccount&lt;/code&gt;. This account instance is required to sign and validate the transaction with its key. If it takes more than one &lt;code&gt;AuthAccount&lt;/code&gt; parameters, then the transaction becomes a &lt;em&gt;multi-signature&lt;/em&gt; transaction. This is the only place our code can access the account object.&lt;/p&gt;

&lt;p&gt;What we did was calling &lt;code&gt;getCapability(/public/NFTReceiver)&lt;/code&gt; on the account instance, then &lt;code&gt;borrow()&lt;/code&gt; to borrow the reference to &lt;code&gt;NFTReceiver&lt;/code&gt; and gain the capability for &lt;code&gt;receiverRef&lt;/code&gt; to receive tokens. We also called &lt;code&gt;borrow(from: /storage/NFTMinter)&lt;/code&gt; on the account to enable &lt;code&gt;minterRef&lt;/code&gt; with the superpower to mint tokens into existence.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;execute&lt;/code&gt; block runs the code within after the &lt;code&gt;prepare&lt;/code&gt; block succeeds. Here, we called &lt;code&gt;mint(metadata: {String: String})&lt;/code&gt; on the &lt;code&gt;minterRef&lt;/code&gt; reference, then moved the newly created &lt;code&gt;@NFT&lt;/code&gt; instance into a &lt;code&gt;newToken&lt;/code&gt; variable. After, we called &lt;code&gt;deposit(token: @NFT)&lt;/code&gt; on the &lt;code&gt;receiverRef&lt;/code&gt; reference, passing &lt;code&gt;&amp;lt;-newToken&lt;/code&gt; (&lt;code&gt;@NFT&lt;/code&gt; resource) as an argument. The newly minted token is now stored in our account's &lt;code&gt;receiverRef&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's try to send this transaction to the running emulator and mint a token! Because this transaction takes a &lt;code&gt;metadata&lt;/code&gt; of type &lt;code&gt;{String: String}&lt;/code&gt; (string to string dictionary), we will need to pass that argument when sending the command via Flow CLI.&lt;/p&gt;

&lt;p&gt;With a bit of luck, you should get a happy output telling you that the transaction is &lt;em&gt;sealed&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flow transactions send src/flow/transaction/MintToken.cdc &lt;span class="s1"&gt;'{"name": "Max", "breed": "Bulldog"}'&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Transaction ID: b10a6f2a1f1d88f99e562e72b2eb4fa3ae690df591d5a9111318b07b8a72e060
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Status      ✅ SEALED
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ID          b10a6f2a1f1d88f99e562e72b2eb4fa3ae690df591d5a9111318b07b8a72e060
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Payer       f8d6e0586b0a20c7
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Authorizers &lt;span class="o"&gt;[&lt;/span&gt;f8d6e0586b0a20c7]
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the &lt;strong&gt;transaction ID&lt;/strong&gt; returned from the transaction. Every transaction returns an ID no matter if it succeeds or not.&lt;/p&gt;

&lt;p&gt;Congratulations on minting your first NFT pet! It does not have a face yet besides just a name and a breed. But later in this tutorial, we will upload static images for our pets onto the Filecoin/IPFS networks using &lt;a href="https://nft.storage/" rel="noopener noreferrer"&gt;nft.storage&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;TransferToken&lt;/code&gt; transaction
&lt;/h3&gt;

&lt;p&gt;Now that we know how to mint Flow NFTs, the next natural step is to learn how to transfer them to different users. Since this transfer action writes to the blockchain and mutates the state, it is also a transaction.&lt;/p&gt;

&lt;p&gt;Before we can transfer a token to another user's account, we need another receiving account to deposit a token to. (We could transfer a token to &lt;em&gt;our&lt;/em&gt; address, but that wouldn't be very interesting, would it?) At the moment, we have been working with only our emulator account so far. So, let's create an account through the Flow CLI.&lt;/p&gt;

&lt;p&gt;First, create a public-private key pair by typing &lt;code&gt;flow keys generate&lt;/code&gt;. The output should look similar to the following, while &lt;strong&gt;the keys will be different&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flow keys generate

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 🔴️ Store private key safely and don&lt;span class="s1"&gt;'t share with anyone!
&amp;gt; Private Key  f410328ecea1757efd2e30b6bc692277a51537f30d8555106a3186b3686a2de6
&amp;gt; Public Key  be393a6e522ae951ed924a88a70ae4cfa4fd59a7411168ebb8330ae47cf02aec489a7e90f6c694c4adf4c95d192fa00143ea8639ea795e306a27e7398cd57bd9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For convenience, let's create a JSON file named &lt;code&gt;.keys.json&lt;/code&gt; in the root directory next to &lt;code&gt;flow.json&lt;/code&gt; so we can read them later on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"private"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f410328ecea1757efd2e30b6bc692277a51537f30d8555106a3186b3686a2de6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"be393a6e522ae951ed924a88a70ae4cfa4fd59a7411168ebb8330ae47cf02aec489a7e90f6c694c4adf4c95d192fa00143ea8639ea795e306a27e7398cd57bd9"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, type this command, replacing &lt;code&gt;&amp;lt;PUBLIC_KEY&amp;gt;&lt;/code&gt; with the public key you generated to create a new account:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flow accounts create —key &amp;lt;PUBLIC_KEY&amp;gt; —signer emulator-account

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Transaction ID: b19f64d3d6e05fdea5dd2ac75832d16dc61008eeacb9d290f153a7a28187d016
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Address 0xf3fcd2c1a78f5eee
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Balance 0.00100000
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Keys    1
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take note of the new address, which should be different from the one shown here. Also, you might notice there is a transaction ID returned. Creating an account is also a transaction, and it was signed by the &lt;code&gt;emulator-account&lt;/code&gt; (hence, &lt;code&gt;—signer emulator-account&lt;/code&gt; flag).&lt;/p&gt;

&lt;p&gt;Before we can use the new address, we need to tell the Flow project about it. Open the &lt;code&gt;flow.json&lt;/code&gt; configuration file, and at the "accounts" field, add the new account name ("test-account" here, but it could be any name), address, and the private key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nl"&gt;"accounts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"emulator-account"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f8d6e0586b0a20c7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bd7a891abd496c9cf933214d2eab26b2a41d614d81fc62763d2c3f65d33326b0"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"test-account"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0xf3fcd2c1a78f5eee"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;PRIVATE_KEY&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this new account created, we are ready to move on to the next step.&lt;/p&gt;

&lt;p&gt;Before we can deposit a token to the new account, we need it to "initialize" its collection. We can do this by creating a transaction for every user to initialize an &lt;code&gt;NFTCollection&lt;/code&gt; in order to receive NFTs.&lt;/p&gt;

&lt;p&gt;Inside &lt;code&gt;/transactions&lt;/code&gt; directory next to &lt;code&gt;MintToken.cdc&lt;/code&gt;, create a new Cadence file named &lt;code&gt;InitCollection.cdc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// InitCollection.cdc&lt;/span&gt;

&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PetStore&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="mi"&gt;0xf8d6e0586b0a20c7&lt;/span&gt;

&lt;span class="c1"&gt;// This transaction will be signed by any user account who wants to receive tokens.&lt;/span&gt;
&lt;span class="n"&gt;transaction&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;acct&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AuthAccount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Create a new empty collection for this account&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.NFTCollection&lt;/span&gt;&lt;span class="nf"&gt;.new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;// store the empty collection in this account storage.&lt;/span&gt;
        &lt;span class="n"&gt;acct&lt;/span&gt;&lt;span class="py"&gt;.save&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;@&lt;/span&gt;&lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.NFTCollection&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;NFTCollection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// Link a public capability for the collection.&lt;/span&gt;
        &lt;span class="c1"&gt;// This is so that the sending account can deposit the token to this account's&lt;/span&gt;
        &lt;span class="c1"&gt;// collection by calling its `deposit(token: @NFT)` method.&lt;/span&gt;
        &lt;span class="n"&gt;acct&lt;/span&gt;&lt;span class="py"&gt;.link&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.NFTReceiver&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;public&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;NFTReceiver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;NFTCollection&lt;/span&gt;&lt;span class="p"&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;This small code will be signed by a receiving account to create an &lt;code&gt;NFTCollection&lt;/code&gt; instance and save it to their own private &lt;code&gt;/storage/NFTCollection&lt;/code&gt; domain (Recall that anything stored in &lt;code&gt;/storage&lt;/code&gt; domain can only be accessible by the current account). In the last step, we linked the &lt;code&gt;NFTCollection&lt;/code&gt; we have just stored to the public domain &lt;code&gt;/public/NFTReceiver&lt;/code&gt; (and in the process, "casting" the collection up to &lt;code&gt;NFTReceiver&lt;/code&gt;) so whoever is sending the token can access this and call &lt;code&gt;deposit(token: @NFT)&lt;/code&gt; on it to deposit the token.&lt;/p&gt;

&lt;p&gt;Try sending this transaction by typing the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flow transactions send src/flow/transaction/InitCollection.cdc —signer test-account
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that &lt;code&gt;test-account&lt;/code&gt; is the name of the new account we created in the &lt;code&gt;flow.json&lt;/code&gt; file. Hopefully, the new account should now have an &lt;code&gt;NFTCollection&lt;/code&gt; created and ready to receive tokens!&lt;/p&gt;

&lt;p&gt;Now, create a Cadence file named &lt;code&gt;TransferToken.cdc&lt;/code&gt; in the &lt;code&gt;/transactions&lt;/code&gt; directory with the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// TransferToken.cdc&lt;/span&gt;

&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PetStore&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="mi"&gt;0xf8d6e0586b0a20c7&lt;/span&gt;

&lt;span class="c1"&gt;// This transaction transfers a token from one user's&lt;/span&gt;
&lt;span class="c1"&gt;// collection to another user's collection.&lt;/span&gt;
&lt;span class="nf"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;recipientAddr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// The field holds the NFT as it is being transferred to the other account.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.NFT&lt;/span&gt;

    &lt;span class="nf"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AuthAccount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// Create a reference to a borrowed `NFTCollection` capability.&lt;/span&gt;
        &lt;span class="c1"&gt;// Note that because `NFTCollection` is publicly defined in the contract, any account can access it.&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;collectionRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="py"&gt;.borrow&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.NFTCollection&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;NFTCollection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nf"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not borrow a reference to the owner's collection"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// Call the withdraw function on the sender's Collection to move the NFT out of the collection&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.token&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;collectionRef&lt;/span&gt;&lt;span class="nf"&gt;.withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;execute&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Get the recipient's public account object&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;recipient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;recipientAddr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// This is familiar since we have done this before in the last `MintToken` transaction block.&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;receiverRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;recipient&lt;/span&gt;&lt;span class="py"&gt;.getCapability&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.NFTReceiver&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;public&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;NFTReceiver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.borrow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nf"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not borrow receiver reference"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// Deposit the NFT in the receivers collection&lt;/span&gt;
        &lt;span class="n"&gt;receiverRef&lt;/span&gt;&lt;span class="nf"&gt;.deposit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// Save the new owner into the `owners` dictionary for look-ups.&lt;/span&gt;
        &lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.owners&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;recipientAddr&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;Recall that in the last steps of our &lt;code&gt;MintToken.cdc&lt;/code&gt; code, we were saving the minted token to our account's &lt;code&gt;NFTCollection&lt;/code&gt; reference stored at &lt;code&gt;/storage/NFTCollection&lt;/code&gt; domain.&lt;/p&gt;

&lt;p&gt;Here in &lt;code&gt;TransferToken.cdc&lt;/code&gt;, we are basically creating a sequel of the minting process. The overall goal is to move the token stored in the sending source account's &lt;code&gt;NFTCollection&lt;/code&gt; to the receiving destination account's &lt;code&gt;NFTCollection&lt;/code&gt; by calling &lt;code&gt;withdraw(id: UInt64)&lt;/code&gt; and &lt;code&gt;deposit(token: @NFT)&lt;/code&gt; on the sending and receiving collections, respectively. Hopefully, by now it shouldn't be too difficult for you to follow along with the comments as you type down each line.&lt;/p&gt;

&lt;p&gt;Two new things that are worth noting are the first line of the &lt;code&gt;execute&lt;/code&gt; block where we call a special built-in function &lt;code&gt;getAccount(_ addr: Address)&lt;/code&gt;, which returns an &lt;code&gt;AuthAccount&lt;/code&gt; instance from an address passed as an argument to this transaction, and the last line, where we update the &lt;code&gt;owners&lt;/code&gt; dictionary on the &lt;code&gt;PetStore&lt;/code&gt; contract with the new address entry to keep track of the current NFT owners.&lt;/p&gt;

&lt;p&gt;Now, let's test out &lt;code&gt;TransferToken.cdc&lt;/code&gt; by typing the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flow transactions send src/flow/transaction/TransferToken.cdc 1 0xf3fcd2c1a78f5eee

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Transaction ID: 4750f983f6b39d87a1e78c84723b312c1010216ba18e233270a5dbf1e0fdd4e6
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Status      ✅ SEALED
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ID          4750f983f6b39d87a1e78c84723b312c1010216ba18e233270a5dbf1e0fdd4e6
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Payer       f8d6e0586b0a20c7
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Authorizers &lt;span class="o"&gt;[&lt;/span&gt;f8d6e0586b0a20c7]
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recall that the &lt;code&gt;transaction&lt;/code&gt; block of &lt;code&gt;TransferToken.cdc&lt;/code&gt; accepts two arguments — A token ID and the recipient's address — which we passed as a list of arguments to the command. Some of you might wonder why we left out &lt;code&gt;--signer&lt;/code&gt; flag for this transaction command, but not the other. Without passing the signing account's name to &lt;code&gt;--signer&lt;/code&gt; flag, the contract owner's account is the signer by default (a.k.a the &lt;code&gt;AuthAccount&lt;/code&gt; argument in the &lt;code&gt;prepare&lt;/code&gt; block).&lt;/p&gt;

&lt;p&gt;Well done! You have just withdrawn and deposited your NFT to another account!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;GetTokenOwner&lt;/code&gt; script
&lt;/h3&gt;

&lt;p&gt;We have learned to write and send transactions. Now, we will learn how to create scripts to read state from the blockchain.&lt;/p&gt;

&lt;p&gt;There are many things we can query using a script, but since we have just transferred a token to &lt;code&gt;test-account&lt;/code&gt;, it would be nice to confirm that the token was actually transferred.&lt;/p&gt;

&lt;p&gt;Let's create a script file named &lt;code&gt;GetTokenOwner.cdc&lt;/code&gt; under the &lt;code&gt;script&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// GetTokenOwner.cdc&lt;/span&gt;

&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PetStore&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="mi"&gt;0xf8d6e0586b0a20c7&lt;/span&gt;

&lt;span class="c1"&gt;// All scripts start with the `main` function,&lt;/span&gt;
&lt;span class="c1"&gt;// which can take an arbitrary number of argument and return&lt;/span&gt;
&lt;span class="c1"&gt;// any type of data.&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// This function accepts a token ID and returns an Address.&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Access the address that owns the NFT with the provided ID.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ownerAddress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.owners&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ownerAddress&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All scripts have an entry function called &lt;code&gt;main&lt;/code&gt;, which can take any number of arguments and return any data type.&lt;/p&gt;

&lt;p&gt;In this script, the &lt;code&gt;main&lt;/code&gt; function accesses the &lt;code&gt;owners&lt;/code&gt; dictionary in the &lt;code&gt;PetStore&lt;/code&gt; contract using the token ID and returns the address of the token's owner, or fails if the value is &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As a reminder, scripts do not require any gas fee or authorization because they only read public data on the blockchain rather than writing to it.&lt;/p&gt;

&lt;p&gt;Here's how to execute a script with the Flow CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flow scripts execute src/flow/script/GetTokenOwner.cdc &amp;lt;TOKEN_ID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;&amp;lt;TOKEN_ID&amp;gt;&lt;/code&gt; is an unsigned integer token ID starting from 1. If you have minted an NFT and transferred it to the &lt;code&gt;test-account&lt;/code&gt;, then replace &lt;code&gt;&amp;lt;TOKEN_ID&amp;gt;&lt;/code&gt; with the token ID. You should get back the address of the &lt;code&gt;test-account&lt;/code&gt; you have created.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;GetTokenMetadata&lt;/code&gt; script
&lt;/h3&gt;

&lt;p&gt;From &lt;code&gt;GetTokenOwner.cdc&lt;/code&gt; script, it takes only a few more steps to create a script that returns a token's metadata.&lt;/p&gt;

&lt;p&gt;We will work on &lt;code&gt;GetTokenMetadata.cdc&lt;/code&gt; which, as the name suggests, gets the metadata of an NFT based on the given ID.&lt;/p&gt;

&lt;p&gt;Recall that there is a &lt;code&gt;metadata&lt;/code&gt; variable in the &lt;code&gt;NFT&lt;/code&gt; resource definition in the contract which stores a &lt;code&gt;{String: String}&lt;/code&gt; dictionary of that &lt;code&gt;NFT&lt;/code&gt;'s metadata. Our script will have to query the right &lt;code&gt;NFT&lt;/code&gt; and read the variable.&lt;/p&gt;

&lt;p&gt;Because we already know how to get an NFT's owner address, all we have to do is to access &lt;code&gt;NFTReceiver&lt;/code&gt; capability of the owner's account and call &lt;code&gt;getTokenMetadata(id: UInt64) : {String: String}&lt;/code&gt; on it to get back the NFT's metadata.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// GetTokenMetadata.cdc&lt;/span&gt;

&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PetStore&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="mi"&gt;0xf8d6e0586b0a20c7&lt;/span&gt;

&lt;span class="c1"&gt;// All scripts start with the `main` function,&lt;/span&gt;
&lt;span class="c1"&gt;// which can take an arbitrary number of argument and return&lt;/span&gt;
&lt;span class="c1"&gt;// any type of data.&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// This function accepts a token ID and returns a metadata dictionary.&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Access the address that owns the NFT with the provided ID.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ownerAddress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.owners&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;

    &lt;span class="c1"&gt;// We encounter the `getAccount(_ addr: Address)` function again.&lt;/span&gt;
    &lt;span class="c1"&gt;// Get the `AuthAccount` instance of the current owner.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ownerAcct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ownerAddress&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Borrow the `NFTReceiver` capability of the owner.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;receiverRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ownerAcct&lt;/span&gt;&lt;span class="py"&gt;.getCapability&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.NFTReceiver&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;public&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;NFTReceiver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.borrow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nf"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not borrow receiver reference"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Happily delegate this query to the owning collection&lt;/span&gt;
    &lt;span class="c1"&gt;// to do the grunt work of getting its token's metadata.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;receiverRef&lt;/span&gt;&lt;span class="nf"&gt;.getTokenMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;id&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;Now, execute the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flow scripts execute src/flow/script/GetTokenMetadata.cdc &amp;lt;TOKEN_ID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we have minted an NFT with the metadata &lt;code&gt;{"name": "Max", "breed": "Bulldog"}&lt;/code&gt; in the previous minting step, then that is what you will get after running the script.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;GetAllTokenIds&lt;/code&gt; (Bonus)
&lt;/h3&gt;

&lt;p&gt;This script is very short and straightforward, and it will become handy&lt;br&gt;
when we build a UI to query tokens based on their IDs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// GetAllTokenIds.cdc&lt;/span&gt;

&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PetStore&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;xPetStore&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;UInt64&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// We basically just return all the UInt64 keys of `owners`&lt;/span&gt;
    &lt;span class="c1"&gt;// dictionary as an array to get all IDs of all tokens in existence.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;PetStore&lt;/span&gt;&lt;span class="py"&gt;.owners.keys&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Wrapping up
&lt;/h3&gt;

&lt;p&gt;Et voila! You have come very far and dare I say you are ready to start building your own Flow NFT app.&lt;/p&gt;

&lt;p&gt;However, user experience is a crucial part in any app. It is more than likely that your users won't be as proficient at the command line as you are. Moreover, it is a bit boring for an NFT store to have faceless NFTs. In the second part, we will start building the UI on top and using &lt;a href="https://nft.storage/" rel="noopener noreferrer"&gt;nft.storage&lt;/a&gt; service to upload and store images of our NFTs instead of the command line using React.&lt;/p&gt;




&lt;h3&gt;
  
  
  Follow me to learn about the brave web3 world and how to program it
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/sULKEgDMX8LcI/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/sULKEgDMX8LcI/giphy.gif" width="245" height="115"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Any idea to make this post even better? I'd like to &lt;a href="https://twitter.com/@pancychain" rel="noopener noreferrer"&gt;hear from you&lt;/a&gt;.
&lt;/h3&gt;

&lt;h3&gt;
  
  
  In a hurry to get to part 2? Check out the &lt;a href="https://nftschool.dev/tutorial/flow-nft-marketplace/" rel="noopener noreferrer"&gt;original version on NFT School&lt;/a&gt;.
&lt;/h3&gt;

</description>
      <category>blockchain</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>react</category>
    </item>
    <item>
      <title>How to Run Spark SQL on Encrypted Data</title>
      <dc:creator>Pan Chasinga</dc:creator>
      <pubDate>Tue, 10 Aug 2021 22:58:00 +0000</pubDate>
      <link>https://dev.to/opaque/how-to-run-spark-sql-on-encrypted-data-1896</link>
      <guid>https://dev.to/opaque/how-to-run-spark-sql-on-encrypted-data-1896</guid>
      <description>&lt;p&gt;Introducing &lt;a href="https://github.com/mc2-project/opaque-sql" rel="noopener noreferrer"&gt;Opaque SQL&lt;/a&gt;, an open-source platform for securely running Spark SQL queries on encrypted data. Built by top systems and security researchers at UC Berkeley, the platform uses &lt;a href="https://en.wikipedia.org/wiki/Software_Guard_Extensions" rel="noopener noreferrer"&gt;hardware enclaves&lt;/a&gt; to securely execute queries on private data in an untrusted environment. &lt;/p&gt;

&lt;p&gt;Opaque SQL partitions the codebase into trusted and untrusted sections to improve runtime and reduce the amount of code that needs to be trusted. The project was designed to introduce as little changes to the Spark API as possible. If you are familiar with Spark SQL, then you already know how to  run secure queries with Opaque SQL.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🚀 Prefer a quick, hands-on ride? Follow the &lt;a href="https://github.com/mc2-project/mc2#quickstart" rel="noopener noreferrer"&gt;Quick Start Guide with Docker&lt;/a&gt; and &lt;a href="https://join.slack.com/t/mc2-project/shared_invite/zt-rt3kxyy8-GS4KA0A351Ysv~GKwy8NEQ" rel="noopener noreferrer"&gt;tell us about your experience&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is Spark SQL?
&lt;/h2&gt;

&lt;p&gt;For those of you who are new, &lt;a href="https://spark.apache.org/" rel="noopener noreferrer"&gt;Apache Spark&lt;/a&gt; is a popular distributed computing framework used by data scientists and engineers for processing large batches of data. One of its modules, &lt;a href="https://spark.apache.org/sql/" rel="noopener noreferrer"&gt;Spark SQL&lt;/a&gt;, allows users to interact with structured, tabular data. This can be done through a &lt;a href="https://spark.apache.org/docs/3.1.1/api/scala/org/apache/spark/sql/Dataset.html" rel="noopener noreferrer"&gt;DataSet/DataFrame&lt;/a&gt; API available in Scala or Python, or by using standard &lt;a href="https://spark.apache.org/docs/latest/api/sql/index.html" rel="noopener noreferrer"&gt;SQL queries&lt;/a&gt;. Here you can see a quick example of both below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// Convert a sequence of tuples into a Spark DataFrame&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;data&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Seq&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;chameleon&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;df&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;toDF&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;pet&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="cm"&gt;/********** DataFrame API **********/&lt;/span&gt;

&lt;span class="c1"&gt;// Create a new DataFrame of rows with `count` greater than 3&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;apiResult&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;$&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;lit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;

&lt;span class="cm"&gt;/******* Writing SQL queries *******/&lt;/span&gt;

&lt;span class="c1"&gt;// Register `df` as a virtual table used to evaluate SQL on&lt;/span&gt;
&lt;span class="nv"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;createOrReplaceTempView&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Create a new DataFrame of rows with `count` greater than 3&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;sqlStrResult&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;spark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nc"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nc"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="nc"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Python via PySpark:&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;# Convert a list of tuples into a Spark DataFrame
&lt;/span&gt;&lt;span class="n"&gt;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;dog&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&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;chameleon&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createDataFrame&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="nf"&gt;toDF&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pet&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;count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;######### Dataframe API ############
&lt;/span&gt;
&lt;span class="c1"&gt;# Create a new DataFrame of rows with `count` greater than 3
&lt;/span&gt;&lt;span class="n"&gt;api_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;lit&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;span class="c1"&gt;######## Write SQL queries #########
&lt;/span&gt;
&lt;span class="c1"&gt;# Register `df` as a virtual table used to evaluate SQL on
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createOrReplaceTempView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;pets&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Create a new DataFrame of rows with `count` greater than 3
&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="n"&gt;sqlStrResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pets&lt;/span&gt; &lt;span class="n"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;😉 If you haven't already, now is a good time to head over and install &lt;a href="https://spark.apache.org/downloads.html" rel="noopener noreferrer"&gt;Spark&lt;/a&gt; and play with the code at the prompt.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Spark Components
&lt;/h3&gt;

&lt;p&gt;For its distributed computing architecture, Spark adopts a master-worker architecture where the master is known as the driver and workers are known as executors.&lt;/p&gt;

&lt;p&gt;The driver is the process where the main Spark program runs. It is responsible for translating a user’s code into jobs to be run on the executors. For example, given a SQL query, the driver builds the SQL plan, performs optimization, and resolves the physical operators that the execution engine will use. It then schedules the compute tasks among the workers and keeps track of their progress until completion. Any metadata, such as the number of data partitions to use or how much memory each worker should have, is set on the driver.&lt;/p&gt;

&lt;p&gt;The executors are responsible for the actual computation. Given a task from the driver, an executor performs the computation and coordinates its progress with the driver. They are launched at the start of every Spark application and can be dynamically removed and added by the driver as needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Computing on encrypted data using MC²
&lt;/h2&gt;

&lt;p&gt;The MC² Project is a collection of tools for secure &lt;strong&gt;M&lt;/strong&gt;ulti-party &lt;strong&gt;C&lt;/strong&gt;ollaboration and &lt;strong&gt;C&lt;/strong&gt;oopetition (hence MC²). This goal is achieved through the use of hardware enclaves. Enclaves provide strong security guarantees, keeping data encrypted in memory while in use. They also provide &lt;a href="https://software.intel.com/content/www/us/en/develop/topics/software-guard-extensions.html" rel="noopener noreferrer"&gt;remote attestation&lt;/a&gt;, which ensures that the enclaves responsible for computation are running the correct sets of instructions. The result is a platform capable of computing on sensitive data in an untrusted environment, such as a public cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Opaque SQL in a Nutshell
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhms8vnk7cldt78zcb5yn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhms8vnk7cldt78zcb5yn.png" alt="Opaque SQL Architectural Diagram" width="800" height="521"&gt;&lt;/a&gt;&lt;/p&gt;
The Opaque SQL query resolution stack. MC² components are in blue.



&lt;p&gt;At a high level, Opaque SQL is a Spark package that uses hardware enclaves to partition Spark’s architecture into untrusted and trusted components. It was originally developed at &lt;a href="https://rise.cs.berkeley.edu/" rel="noopener noreferrer"&gt;UC Berkeley’s RISELab&lt;/a&gt; as the implementation of a &lt;a href="https://www.usenix.org/system/files/conference/nsdi17/nsdi17-zheng.pdf" rel="noopener noreferrer"&gt;NSDI 2017 paper&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Untrusted Driver
&lt;/h3&gt;

&lt;p&gt;While the query and table schemas are not hidden because the Spark driver still needs to perform planning, the driver is only able to access completely encrypted data. The physical plan built will contain entirely encrypted operators in place of vanilla Spark operators. (However, since the driver is building the plan, the client needs to verify that the plan created is correct; support for this is currently a work-in-progress and will be part of the next release.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Enclaves on Executor Machines
&lt;/h3&gt;

&lt;p&gt;During execution, the executor program calls into Opaque SQL’s native library that’s loaded inside the hardware enclave. The native library provides encrypted SQL operators that can execute on encrypted, sensitive data inside the enclave. Any private column data such as SSNs, bank account numbers, or &lt;a href="https://www.hhs.gov/answers/hipaa/what-is-phi/index.html" rel="noopener noreferrer"&gt;PHI&lt;/a&gt; remains encrypted in memory and is protected by the enclave.&lt;/p&gt;

&lt;h2&gt;
  
  
  the MC² Client: The Entry Point
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/mc2-project/mc2" rel="noopener noreferrer"&gt;MC² Client&lt;/a&gt; is responsible for communicating with the Spark driver and performing remote attestation and query submission. It is a trusted component that is located on the user’s machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Remote attestation
&lt;/h3&gt;

&lt;p&gt;Attest, what? To put it simply, remote attestation is just a way to have the user verify that the enclaves were initialized correctly with the right code to run. The client talks to the driver, which forwards attestation information to the enclaves that are running on the executors. No enclave is able to decrypt any data until attestation is complete and the results are verified by the user. Think of it as a way for you, the data owner, to sign off and trust the enclave to start running code on your behalf.&lt;/p&gt;

&lt;h3&gt;
  
  
  Query submission
&lt;/h3&gt;

&lt;p&gt;Query submission happens after attestation is completed successfully, and is the step where Spark code is remotely submitted to the driver for evaluation. Any intermediate values remain encrypted throughout the lifetime of the execution stage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx726pnmxct56slsijcik.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx726pnmxct56slsijcik.png" alt="MC2 Client Diagram" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;
How the MC² client communicates with Opaque SQL



&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;A key design for Opaque SQL is to have our API as similar to Spark SQL as possible. An encrypted DataFrame is loaded in through a special format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// Unencrypted&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;df&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;spark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;read&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nv"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;databricks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;spark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;csv&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Encrypted&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;dfEncrypted&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;spark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;read&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nv"&gt;edu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;berkeley&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;cs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;rise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;opaque&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;EncryptedSource&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After loading, Spark transformations are applied exactly the same as vanilla Spark, only with new encrypted physical operators being created during planning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;dfEncrypted&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;$&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;lit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;explain&lt;/span&gt;
&lt;span class="c1"&gt;// == Physical Plan ==&lt;/span&gt;
&lt;span class="c1"&gt;// EncryptedFilter (count#5 &amp;gt; 3)&lt;/span&gt;
&lt;span class="c1"&gt;// +- EncryptedLocalTableScan [word#4, count#5], [[foo,4], [bar,1], [baz,5]]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To save the result after a query has been created, use the same format as loading:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;
&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;write&lt;/span&gt; &lt;span class="o"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nv"&gt;edu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;berkeley&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;cs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;rise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;opaque&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;EncryptedSource&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 Now is the time to check our complete &lt;a href="https://mc2-project.github.io/opaque-sql/usage/functionality.html" rel="noopener noreferrer"&gt;API docs&lt;/a&gt; to continue your learning journey.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Opaque SQL enables analytics processing over encrypted DataFrames, with little overhead to vanilla Spark. In turn, this extension protects data-in-use in the cloud as well as at rest. Queries are submitted remotely with the help of the MC² Client, an easy-to-use interface for communicating with all compute services on the MC² stack.&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://mc2-project.github.io/resources.html#blogs" rel="noopener noreferrer"&gt;more blog posts&lt;/a&gt; on how to securely process data with MC² Project. We would love your contributions ✋ and support ⭐! Please check out the &lt;a href="https://github.com/mc2-project/mc2" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt; to see how you can contribute. No contribution is too small.&lt;/p&gt;




&lt;p&gt;Edited by &lt;a class="mentioned-user" href="https://dev.to/pancy"&gt;@pancy&lt;/a&gt;. Originally posted &lt;a href="https://towardsdatascience.com/how-to-run-spark-sql-on-encrypted-data-c10adf64619" rel="noopener noreferrer"&gt;here&lt;/a&gt; by &lt;a class="mentioned-user" href="https://dev.to/octaviansima"&gt;@octaviansima&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>datascience</category>
      <category>sql</category>
      <category>scala</category>
      <category>database</category>
    </item>
    <item>
      <title>Python Should Learn from Javascript</title>
      <dc:creator>Pan Chasinga</dc:creator>
      <pubDate>Fri, 16 Jul 2021 04:16:48 +0000</pubDate>
      <link>https://dev.to/pancy/python-should-learn-from-javascript-2jp7</link>
      <guid>https://dev.to/pancy/python-should-learn-from-javascript-2jp7</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;If Javascript, an old language with so many flaws, could evolve like it did, Python could learn from it and step out of its ivory tower.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This isn’t a targeted attack on Python. It is a constructive opinion from a programmer who had started his career and spent years working with it. So brace yourself — Python is evolving slowly and could use the level of improvement Javascript has had.&lt;/p&gt;

&lt;p&gt;Javascript has come a long way since being the most hated but widely-used scripting language of the web that was created in less than a month. With ES6 and the sister language Typescript (that arguably helped propelled JS ecosystem to a new height), Javascript is no longer an ugly language to be looked down to. For instance, it has changed dramatically from a callback-based language into promise-based and async-await syntax in what seemed like a blink of an eye compared to the rate Python moved to reach a unanimous support for v3.&lt;br&gt;
A very impressive deed of Javascript, in my opinion, is its move toward functional programming. The syntax is clean, learning from the great functional languages like ML. This alone sprouted so many great improvements to the ecosystem such as React, ReasonML, and more. Let’s admit it, there’s a lot to love about modern Javascript compared to Python 3.&lt;br&gt;
Until recently, Python had always been under tight moderation of its creator, Guido Rossum. While that had its good parts, the downside is the language’s slow development due to the bottleneck from the resistance of the creator.&lt;/p&gt;
&lt;h2&gt;
  
  
  Lambda what?
&lt;/h2&gt;

&lt;p&gt;For example, Guido Rossum distaste for lambdas was well-known. Perhaps the goal of Python’s half-baked lambda syntax that I’ve always found clumsy and useless to this day has always been to keep users from using it in the first place.&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="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is nothing wrong with this syntax, since many Lisp dialects also use the keyword lambda to initialize an anonymous function. However, being a whitespace-significant language and not expression-based, the lambda syntax of Python makes a cumbersome and ambiguous experience in applying lambdas:&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="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now who says Python is still easy to read? This kind of beats the very reasons of lambdas, which are expressiveness and clarity. This appears ambiguous to me. Compared to the anonymous function syntax of ES6:&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;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although not the cleanest (the cleanest lambda syntax goes to Lisp), the applications are clear, considered you know it is right-associated. The only thing Javascript is missing is piping syntax, which would have made it an even more expressive programming tool.&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;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  map(function, iterable, …)
&lt;/h1&gt;

&lt;p&gt;Admit it, you either hate or feel meh over mapping iterables in Python, or you might not even use it.&lt;br&gt;
Most languages, including Javascript, treat mapping function as the iterable or iterator method. This removes the iterable from the argument list and makes it much clearer with the callback function being the last argument.&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;let&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt; &lt;span class="o"&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="mi"&gt;2&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;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is another map function in Rust:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&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="mi"&gt;2&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;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some functional languages such as Haskell and Ocaml use the &lt;code&gt;module:function&lt;/code&gt; approach, which is similar to what Python does. However, their expression-based syntax and unambiguous scoped variable binding makes the code readable and easy to get right. Here is a sample of a map function in Ocaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;double&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;double&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="mi"&gt;2&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;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You need to do this in Python:&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="n"&gt;double&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;double&lt;/span&gt;&lt;span class="p"&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="mi"&gt;2&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;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may think Python looks way cleaner here, which you may be right. But consider most use cases where you chain operators.&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;let&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt; &lt;span class="o"&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="mi"&gt;2&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;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Ocaml, it’s just magical:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&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="mi"&gt;2&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;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fold_left&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="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’ll leave you to write an equivalent in Python (HINT: It is impossible to read!)&lt;/p&gt;

&lt;h2&gt;
  
  
  Decorators
&lt;/h2&gt;

&lt;p&gt;Decorators are my pet peeves. To me, they were the inflection point from Python mantra of “there’s only one way to do things” and the promise of a transparent, non-magical language.&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&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;inner&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;                                                                                            
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                                                                                     
        &lt;span class="nf"&gt;func&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;inner&lt;/span&gt;                                                                                            

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;                                                                                                 
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                                                                                         

&lt;span class="c1"&gt;# `hello` is a decorator function                                                                                          
&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;hello&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="nf"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# prints "Hello Alice"
&lt;/span&gt;&lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;short&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;handed&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="nd"&gt;@hello&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&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;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# prints "Hello Alice"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Decorators “hide” the logic essential and completely change the behavior of a “host” function it decorates, which is nothing short of magical to more than half of all Python users today. Albeit useful, it still puzzles me to these days why Python developers decided to adopt decorators.&lt;/p&gt;

&lt;p&gt;Somehow, Javascript has found its niche in everything. However, its ES6 improvement and Typescript enhancement has made it even more enticing to users who dislike it (myself, for one, had become a serious Javascript user after ES6). Python similarly hold a very big niche, including web programming, data science, and machine learning, which warrant its ivory tower. However, today’s tools are evolving fast, and not changing seems like standing still waiting for a new kid on the block to beat it in the home court.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you like my writing, please follow me on &lt;a href="https://twitter.com/pancychain" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; to get more of technical opinions. I’m also on &lt;a href="https://medium.com/@pancy" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; and would love to see you there!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>python</category>
      <category>javascript</category>
      <category>rust</category>
      <category>ocaml</category>
    </item>
    <item>
      <title>EP1: Rust Ownership for Toddlers</title>
      <dc:creator>Pan Chasinga</dc:creator>
      <pubDate>Tue, 22 Jun 2021 16:00:07 +0000</pubDate>
      <link>https://dev.to/pancy/ep1-rust-ownership-for-toddlers-3pe1</link>
      <guid>https://dev.to/pancy/ep1-rust-ownership-for-toddlers-3pe1</guid>
      <description>&lt;p&gt;"Rust is too hard to learn," You whined.&lt;br&gt;
"Maybe because you're a toddler?"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp3lcoybi7x59rej9bts8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp3lcoybi7x59rej9bts8.jpg" alt="Success Kid Meme" width="636" height="423"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🧸 Ownership
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Ownership IS the only big concept in Rust. It is not unique, and C++ has it too. Understand this well.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Repeat after me, &lt;strong&gt;"Thou shall be the only one owning a toy."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's it. Alice has a toy, then Bob snatches it from Alice. Alice no longer has the toy. Bob runs away and gets bullied by Tim, looting the toy. Then Bob has no toy. Tim has the toy.&lt;/p&gt;

&lt;p&gt;If you later asked Alice for the toy, she would just cry and slap you on and on, yelling, "Bob took my toy!"&lt;/p&gt;

&lt;p&gt;If you asked Bob to get back the toy, he would lash out with a black eye. "Tim has it!"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F87xxnhzq8obaeegsrce8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F87xxnhzq8obaeegsrce8.jpg" alt="Angry Girl Meme" width="500" height="845"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Teddy"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="cd"&gt;/// Bob suddenly shows up and snatches it from Alice.&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;bob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="cd"&gt;/// "Bob took it!" Alice cried.&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice, where is the {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;tim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bob&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="cd"&gt;/// "Tim stole it!" Bob lashed out.&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Bob, did you take the {} from Alice?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="cd"&gt;/// Tim, an alien under a kid skin, eats the bear.&lt;/span&gt;
        &lt;span class="cd"&gt;/// Then, Tim and Bob vanishes into ether.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cd"&gt;/// "Who's Bob?" Alice said, Teddy no longer in her arm.&lt;/span&gt;
    &lt;span class="cd"&gt;/// Cue the X-file music...&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice, did Bob return the {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alice&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;h3&gt;
  
  
  🔮 Reflect
&lt;/h3&gt;

&lt;p&gt;Although this may sound confusing, it is pretty simple in the real, physical world. You were just too spoiled by your X language. Here is the hard fact -- You just can't have more of a thing. A piece of data is not made of pixie dust. It is a bunch of electrons making tricks on a couple of latches to spell out enough 0 and 1 digits to make up a piece of data. As real as a teddy bear.&lt;/p&gt;

&lt;h3&gt;
  
  
  🐍 What other languages do
&lt;/h3&gt;

&lt;p&gt;What most languages do is basically telling Alice and Bob to share, which they can on a good day. On a bad one, they are yanking the toy on each end. On the worst, either one might misplace it and the other explodes. This one hip language named after a fat snake takes it too far by buying a duplicate for every toy for Alice, Bob, Tim, and any other kids who want to play with it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🍼 Try-sies&lt;br&gt;
Instead of a &lt;code&gt;String::from("Teddy")&lt;/code&gt;, try a string literal "Teddy" or an integer and keep the code. What happens? Use this &lt;a href="https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2018&amp;amp;gist=54aebc47a49e72cd4c554268cf407109" rel="noopener noreferrer"&gt;playground&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sensibly, in order for Alice to have the toy, Bob (or whoever was owning it) should return the toy to her.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="cd"&gt;/// mut means I can change what I have later.&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Toy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Teddy"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;bob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;tim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bob&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;tim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;daghan_does_something&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tim&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cd"&gt;/// "No!" Alice yelled.&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Did you get the {:?} back, Alice?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;alice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tim&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cd"&gt;/// Print just fine!&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Now, did you get the {:?} back?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since Tim eventually returned the toy back to Alice, Alice is happy.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Stay tuned for EP2: Rust Borrows for Toddlers: All You Gotta Do is Ask.
&lt;/h3&gt;

&lt;p&gt;👀 &lt;strong&gt;Follow&lt;/strong&gt; me so you don't miss the next episodes!&lt;br&gt;
🦄 &lt;strong&gt;Upvote&lt;/strong&gt; this so Netflax renews the episodes!&lt;/p&gt;

&lt;p&gt;I'm also on &lt;a href="https://pancy.medium.com/" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; and &lt;a href="https://twitter.com/pancychain" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;. Come say 👋&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>rust</category>
      <category>tutorial</category>
      <category>codepen</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
